今天看了.net平台SOA架构的部分书籍,自己也试着做些例子。本以为会比较顺利,结果还是费了些周折,兹记下以备查阅。
先列出SVC的内容:
namespace WcfFundamentals
{
[ServiceContract(Namespace = "SimpleXmlService")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SimpleXmlService
{
// 添加 [WebGet] 属性以使用 HTTP GET
[WebGet]
[OperationContract]
public XmlElement HelloWorld()
{
var doc = new XmlDocument();
doc.InnerXml = "<message>Hello XML World!</message>";
return doc.DocumentElement;
}
}
}
写法1:下面这样可以输出WSDL:但是不能被AJAX以HTTP Get访问
<system.serviceModel>
<behaviors>
<endpointBehaviors>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="PoxBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="WcfFundamentals.SimpleXmlService" behaviorConfiguration="PoxBehavior">
<endpoint address="" binding="webHttpBinding"contract="WcfFundamentals.SimpleXmlService" />
</service>
</services>
</system.serviceModel>
简评:这个是常见的情况,ASP.net调这个服务是能用的;要让JavaScript的HTTP Get方式调用Web服务除了方法上加属性外,Web.Config也要做配置,上面就是因为没有<webHttp/>配置。
写法2:(错误的写法)
<system.serviceModel>
<behaviors>
<endpointBehaviors>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="PoxBehavior">
@H_403_301@ <webHttp/></behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="WcfFundamentals.SimpleXmlService"behaviorConfiguration="PoxBehavior">
<endpoint address="" binding="webHttpBinding"contract="WcfFundamentals.SimpleXmlService" />
</service>
</services>
</system.serviceModel>
简评:<webHttp/>配置是加上了,但是加的地方不对,因为<webHttp/>是针对endpointBehaviors的,放在<serviceBehaviors>节不对。错误也是反面经验,所以列出来,去伪方存真。
写法3:(错误的写法)
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="PoxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="WcfFundamentals.SimpleXmlService"behaviorConfiguration="PoxBehavior">
<endpoint address=""binding="webHttpBinding"contract="WcfFundamentals.SimpleXmlService" />
</service>
</services>
</system.serviceModel>
简评:<webHttp/>配置的地方是对了,但是不起作用,因为<service>节的behaviorConfiguration属性不会指向<endpointBehaviors>节,只认 <serviceBehaviors>节。既不能输出WSDL,AJAX HTTP Get也不能访问。
写法4:AJAX HTTP Get能够访问的写法:(但是不能用IIS生成WSDL,提示“当前已禁用此服务的元数据发布”)
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="PoxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="WcfFundamentals.SimpleXmlService" >
<endpoint address="" behaviorConfiguration="PoxBehavior"binding="webHttpBinding"contract="WcfFundamentals.SimpleXmlService" />
</service>
</services>
</system.serviceModel>
简评:为了让behaviorConfiguration属性指向<endpointBehaviors>节,需要配置endpoint的(而不是service 的)behaviorConfiguration,终于AJAX能访问了。但是问题又来了,不能用IIS生成WSDL,这意味着无法使用IDE工具配合C#来测试方法。
写法5:AJAX HTTP Get能够访问的写法,也能用IIS生成WSDL
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="PoxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="PoxBehavior2">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="WcfFundamentals.SimpleXmlService" behaviorConfiguration="PoxBehavior2">
<endpoint address=""behaviorConfiguration="PoxBehavior"binding="webHttpBinding" contract="WcfFundamentals.SimpleXmlService" />
</service>
</services>
</system.serviceModel>
简评:为了能AJAX HTTP Get能够访问,也能用IIS生成WSDL,需要对service和endpoint的behaviorConfiguration分别配置,指向不同的行为配置节,这是彻底解决方法,也是两全其美的方法。
写法6:恶搞的写法(是可以用的)
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="PoxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="PoxBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="WcfFundamentals.SimpleXmlService" behaviorConfiguration="PoxBehavior">
<endpoint address="" behaviorConfiguration="PoxBehavior"binding="webHttpBinding" contract="WcfFundamentals.SimpleXmlService" />
</service>
</services>
</system.serviceModel>简评:之所以称恶搞,是因为endpointBehaviors和serviceBehaviors节各有一个同名的PoxBehavior。并且这样的配置是可以被AJAX HTTP Get访问,也能用IIS生成WSDL的。于是在不知缘由的情况下,容易被这个搞蒙。这是因为service的behaviorConfiguration属性指向serviceBehaviors下的PoxBehavior,而endpoint的behaviorConfiguration属性指向endpointBehaviors下的PoxBehavior,endpointBehaviors和serviceBehaviors节各自的PoxBehavior并不冲突。