刚接触WCF,看了artech的WCF学习之旅(1),照着操作了一次,在进行IIS寄宿时,开始始终不成功。在完成之时写下这篇笔记。
首先编写契约(Contract),代码如下:
using System.ServiceModel;
namespace xiaohai.WCFService.Contracts
{
[ServiceContract]
public interface ICalculator
{
[OperationContract]
public double Add(double x, double y);
[OperationContract]
public double Substract(double x, double y);
[OperationContract]
public double Multiply(double x, double y);
[OperationContract]
public double Divide(double x, double y);
}
}
接着实现服务(CalculatorService),代码如是:
using System.ServiceModel;
using xiaohai.WCFService.Contracts;
namespace xiaohai.WCFService.Services
{
public class CalculatorService : ICalculator
{
public double Add(double x, double y)
{
return x + y;
}
public double Substract(double x, double y)
{
return x - y;
}
public double Multiply(double x, double y)
{
return x * y;
}
public double Divide(double x, double y)
{
return x / y;
}
}
}
之后就是寄宿。先使用自我寄宿,编写宿主程序,代码如下:
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using xiaohai.WCFService.Contracts;
using xiaohai.WCFService.Services;
class Progaram
{
static void Main()
{
using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://localhost:8001/CalculatorService");
if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
{
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri("http://localhost:8001/CalculatorService/Metadata");
host.Description.Behaviors.Add(behavior);
}
host.Opened += delegate { Console.WriteLine("The Calculator Service is Opened ......"); };
host.Open();
Console.ReadLine();
}
}
}
这是使用编程方式添加终结点,也可以使用应用程序的配置来添加终结点。配置的内容如下
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel >
<services >
<service name ="xiaohai.WCFService.Services.CalculatorService" behaviorConfiguration ="metadata">
<endpoint address ="http://localhost:8001/CalculatorService" binding ="wsHttpBinding"
contract ="xiaohai.WCFService.Contracts.ICalculator"/>
</service>
</services>
<behaviors >
<serviceBehaviors >
<behavior name ="metadata">
<serviceMetadata httpGetEnabled ="true " httpGetUrl ="http://localhost:8001/CalculatorService/Metadata"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
相应的代码调整为:
class Progaram
{
static void Main()
{
using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
host.Opened += delegate { Console.WriteLine("The Calculator Service is Opened ......"); };
host.Open();
Console.ReadLine();
}
}
}
最后做的就是编写客户端:右键单击Client项目。选择“添加服务引用” ,运行宿主程序Hosting,输入元数据地址,并修改命名空间(如CalculatorClient)点确定即可。之后客户端的代码为:
using System;
using Client.CalculatorClient;
class Program
{
static void Main()
{
using (CalculatorClient proxy = new CalculatorClient())
{
Console.WriteLine("x+y={2},When x={0} y={1}",1,2,proxy .Add (1,2));
Console.WriteLine("x-y={2},When x={0} y={1}", 10, 2.1, proxy.Substract (10, 2.1));
Console.WriteLine("x*y={2},When x={0} y={1}", 9.9, 5.5, proxy.Multiply (9.9, 5.5));
Console.WriteLine("x/y={2},When x={0} y={1}", 10, 2.8, proxy.Divide (10, 2.8));
Console.ReadLine();
}
}
}
当然。客户端也可以使用配置的方法,配置可以为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel >
<client >
<endpoint address ="http://localhost:8001/CalculatorService" binding ="wsHttpBinding"
contract ="xiaohai.WCFService.Contracts.ICalculator" name ="calculator"/>
</client>
</system.serviceModel>
</configuration>
相应的客户端的代码可以为:
using System;
using System.ServiceModel;
using xiaohai.WCFService.Contracts;
class Program
{
static void Main()
{
using (ChannelFactory<ICalculator > channel =new ChannelFactory<ICalculator>("calculator"))
{
ICalculator proxy = channel.CreateChannel();
Console.WriteLine("x+y={2},When x={0} y={1}",1,2,proxy .Add (1,2));
Console.WriteLine("x-y={2},When x={0} y={1}", 10, 2.1, proxy.Substract (10, 2.1));
Console.WriteLine("x*y={2},When x={0} y={1}", 9.9, 5.5, proxy.Multiply (9.9, 5.5));
Console.WriteLine("x/y={2},When x={0} y={1}", 10, 2.8, proxy.Divide (10, 2.8));
Console.ReadLine();
}
}
}
以上是通过自我寄宿的方法进行。还可以通过IIS寄宿。
首先在IIS中新建虚拟目录。假设虚拟目录就设置为Service项目所在文件夹中。在Services文件中新建一个配置文件命名为web.config
其内容为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel >
<services >
<service name ="xiaohai.WCFService.Services.CalculatorService" behaviorConfiguration ="metadata" >
<endpoint binding ="wsHttpBinding" contract ="xiaohai.WCFService.Contracts.ICalculator" />
</service>
</services>
<behaviors >
<serviceBehaviors >
<behavior name ="metadata">
<serviceMetadata httpGetEnabled ="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled ="true"/>
</system.webServer>
</configuration>
在同一目录下新建一个名为MyServices.svc的文件。其内容为 <%@ServiceHost Service="xiaohai.WCFService.Services.CalculatorService" %>
现在修改客户端的配置为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel >
<client >
<endpoint address ="http://localhost:9999/MyServices.svc" binding ="wsHttpBinding"
contract ="xiaohai.WCFService.Contracts.ICalculator" name ="calculator"/>
</client>
</system.serviceModel>
</configuration>
到此为止IIS寄宿完成。
另外在WCF 4.0中可以省略svc文件的建立。只用把web.config修改为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel >
<serviceHostingEnvironment >
<serviceActivations >
<add relativeAddress ="MyService.svc" service ="xiaohai.WCFService.Services.CalculatorService"/>
</serviceActivations>
</serviceHostingEnvironment>
<services >
<service name ="xiaohai.WCFService.Services.CalculatorService" behaviorConfiguration ="metadata" >
<endpoint binding ="wsHttpBinding" contract ="xiaohai.WCFService.Contracts.ICalculator" />
</service>
</services>
<behaviors >
<serviceBehaviors >
<behavior name ="metadata">
<serviceMetadata httpGetEnabled ="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled ="true"/>
</system.webServer>
</configuration>
需要注意的是:在没有.svc文件的情形下,应该在IIS中选择添加应用程序而不是选择虚拟目录。在有.svc文件的条件下。选择添加虚拟目录。还有在网站的基本设置中修改应用程序池为 Asp .net 4.0 而不是DefaultAppPool。