上一篇我们写了WCF控制台寄宿运用程序,其实不管宿主是Winform/WPF或者Windows服务,都是通过Button或者服务起停变更ServiceHost的开闭函数,虽换了框架,但是内容还是控制台程序里面的程序。
WCF也是一款Web应用发布,注定它能进行IIS发布,那么不禁联想到Web服务。我们知道,每一个ASP.NET Web服务都具有一个.asmx文本文件,客户端通过访问.asmx文件实现对相应web服务的调用。与之类似,每个WCF服务也具有一个对应的文本文件,其文件扩展名为.svc。基于IIS的服务寄宿要求相应的WCF服务具有相应的.svc文件,.svc文件部署于IIS站点中,对WCF服务的调用体现在对.svc文件的访问上。
新建一个WCF服务应用程序,自动生成IService1.cs、Service1.svc、Service1.svc.cs。IService1.cs是添加接口方法的地方,把函数写在IService1接口下。Service1.svc.cs是实现接口类,把实现方法写在class Service1中。至于Service1.svc,svc文件相当于asmx文件。
//IService1.cs文件 接口添加函数
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: 在此添加您的服务操作
[OperationContract]
string Run(int distance);
}
//Service1.svc.cs文件函数实现
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
public string Run(int distance)
{
return "行驶了" + distance.ToString();
}
}
服务创建到寄宿过程,可以用代码实现,也可以在*.config文件中配置完成。采用这种文件配置方式,要完成三个部分,即Behavior、Service和Binding,可以看如下代码:
<system.serviceModel>
<services>
<service name="wcf_IIS.Service1" behaviorConfiguration="">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBindingCnfg"
contract="wcf_IIS.IService1"></endpoint>
<endpoint contract="wcf_IIS.IService1" binding="mexHttpBinding" address="mex" />
</service>
</services>
<!-- 配置服务端可接收最大数据容量 -->
<bindings>
<wsHttpBinding>
<binding name="NewBindingCnfg" maxReceivedMessageSize="655360000" />
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<!-- name务必为空,否则发布不了 -->
<behavior name="">
<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
address这里为空,真实地址以IIS的url。编译调试,服务相当于挂在vs专供测试人员调试轻量级IIS Express中,在工程属性——Web中可以看到,这个url就是服务地址,下来我们可以用客户端访问。
现在情况我已经挂在本地的IIS中,进行客户端调用,建一个控制台客户端。先讨论添加服务引用方式,添加完成,app.config会自动生成xml配置,见下代码。生成后才可以去配置一些额外的属性。
<system.serviceModel>
<client>
<endpoint address="http://localhost:8086/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1">
<identity>
<servicePrincipalName value="host/Pc-Yang" />
</identity>
</endpoint>
<endpoint address="http://localhost:8086/Service1.svc/mex" binding="wsHttpBinding"
bindingConfiguration="MetadataExchangeHttpBinding_IService1"
contract="ServiceReference1.IService1" name="MetadataExchangeHttpBinding_IService1"/>
</client>
<bindings>
<wsHttpBinding>
<!--<生成后可以自己配置发送端可最大接受数据容量属性 maxReceivedMessageSize>-->
<binding name="WSHttpBinding_IService1" maxReceivedMessageSize="100000" />
<binding name="MetadataExchangeHttpBinding_IService1">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
再看与之匹配的后台调用函数代码,注意这里是两个终结点,要明确指明用哪个。
class Program
{
static void Main(string[] args)
{
//new时候构造填终结点名称
wcf_client.ServiceReference1.Service1Client wcfclient = new wcf_client.ServiceReference1.Service1Client("WSHttpBinding_IService1");
Console.WriteLine(wcfclient.Run(3));
}
}
我们再来讨论另一种自己代码创建的访问代理对象,会报错" 远程服务器返回了意外响应: (405) Method Not Allowed",至于原因,可能跟IIS有关,也有可能别的,有兴趣的可以再去研究下。
class Program
{
static void Main(string[] args)
{
using (var cf = new ChannelFactory<wcf_IIS.IService1>(new WSHttpBinding(), "http://localhost:8086/"))
{
Console.WriteLine(cf.CreateChannel().Run(3));
Console.Read();
}
}
}
最后,说下如何放到IIS上,跟web服务发布差不多。新建一个网站,地址是本机或服务器,端口自己确定,不冲突就行。物理路径是指向发布包,必须确保有这几个文件存在。
以上就是WCF IIS发布全过程,写的有点仓促,比较忙这阶段。
总结
IIS发布,新建服务应用程序,服务端只可通过配置文件来实现服务的创建、寄宿和暴露元数据,不能通过代码;客户端可以采用引用服务方式来生成代理对象,至于代码写代理对象,实验没成功。
WCF控制台自我寄宿,服务端只可通过配置文件来实现服务的创建、寄宿和暴露元数据,也可通过代码;客户端可以采用引用服务方式来生成代理对象,也可代码写代理对象。