宿主为IIS
1.建立服务契约接口,采用声明式编程,在接口上加特性(Attribute)
[ServiceContract(Namespace="http://localhost/WCFService")]// Namespace防止重复
interface ICalculator
{
[OperationContract] //操作契约
double Add(double a, double b);
}
// 使用下面示例中说明的数据协定将复合类型添加到服务操作
[DataContract]
public class CompositeType
{
string stringValue = "Hello ";
[DataMember] //数据契约,作为元数据封装到服务里
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
2.实现该接口(1,2可放在一个文件)
class Calculator:ICalculator
{
public double Add(double a, double b)
{
return a + b;
}
3.写配置文件Web.config
<system.serviceModel>
<services>
<service name="WCFService.Calculator" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address=""
binding="wsHttpBinding"
contract="WCFService.ICalculator" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
4. IIS设置虚拟目录,指向.svc文件所在目录,然后网页打开该.SVC文件,按提示用工具svcutil.exe生成客户端文件代理契约实现类比如Service.cs(一个服务契约接口实现类对应一个文件)和客户端配置文件output.config,客户端不实现方法,都是调用服务器端函数和类)
5.在客户端(Web或应用程序)引用或者Svcutil.exe自动生成客户端,可以将Svcutil.exe和dll考到其他目录,方便自动生成需要。
在客户端引用:
在同一个解决方案中不用运行宿主程序就可以找到并引用该服务,如果是不同的解决方案,客户端添加服务引用时一定要先运行宿主程序(如果是同一解决方案中就从debug文件夹中运行先运行宿主程序,这个问题捆饶了我好几天,然后再添加服务引用,要不是找不到服务的,不过想想也很显然,当初怎么没注意呢)。
Svcutil.exe自动生成客户端:先启动宿主
宿主为控制台,不同之处为:
3.写配置文件app.config,这个是VS2008中新建 WCF服务库自动生成的,baseAddresses用来指向服务终节点服务地址,客户端使用这个地址找到服务端的终节点,如果是本机配置一定要加端口号,IIS宿主配置的话不用配置这个地址,明显的它已经有地址了。Endpoint服务终节点,常说的ABC,消息发送地址,绑定的通信协议,不同的通信协议针对不同的应用环境,正是看中这一点,在分布式环境下的解决方案会比webservice好,服务契约,使用命名空间+接口名字,如
contract="WcfServiceLibrary1.IService1"。另外,如果在配置文件里写两个终节点的<endpoint address="".. address不可一样,否则第2个服务无法启用
<!-- 部署服务库项目时,必须将配置文件的内容添加到
主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
<system.serviceModel>
<bindings />
<client />
<services>
<service name="WcfServiceLibrary1.Service1" behaviorConfiguration="WcfServiceLibrary1.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
<endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1">
< identity >
<dns value="localhost"/>
</identity>
</endpoint>
< endpoint address = "mex " binding= "mexHttpBinding " contract= "IMetadataExchange "/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceLibrary1.Service1Behavior">
<!-- 为避免泄漏元数据信息,
请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
<serviceMetadata httpGetEnabled="True"/>
< serviceDebug includeExceptionDetailInFaults = "False " />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
4.写宿主程序
using(ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary1.Service1)))
{
host.Opened+=new EventHandler(delegate(object sender,EventArgs e){
Console.WriteLine("Service is Opened!");
foreach (var channelDiapacher in host.ChannelDispatchers)
{
Console.WriteLine("listen url:" + channelDiapacher.Listener.Uri.ToString());
}
});
host.Open();
}
Console.Read();
其他,不用配置文件直接运行服务
Uri httpAddress = new Uri("http://localhost:8002/WCFService22")
using (ServiceHost host = new ServiceHost(typeof(WCFService.WCFService), httpAddress))//加httpAddress
{
///添加服务终节点///
host.AddServiceEndpoint(typeof(WCFService.IWCFService), new WSHttpBinding(),
httpAddress/*string.Empty*/);//httpAddress如果有为多个终节点服务地址可‘,’分割
///元数据终节点//////
ServiceMetadataBehavior behavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
{
if (behavior == null)
{
behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);
}
else
{
behavior.HttpGetEnabled = true;
}
}
host.Open();
//显示运行状态
Console.WriteLine("Host state is {0}",host.State);
//等待输入即停止服务
Console.Read();
}
}
另外,新建项目时如果宿主为IIS则项目为WEB服务程序,宿主为控制台则为控制台程序。
测试 WCF SVC服务,如 C :"> WcfTestClient http://localhost:4691/WCFForumService.svc
WcfTestClient 地址C:"Program Files"Microsoft Visual Studio 9.0"Common7"IDE