我有一个 WCF 服务,它有一个具有以下签名的方法:
object GetCommand(Guid apiKey, SocialService service, string name, object argument);
它使用对象作为返回类型和最后一个参数的原因是,应该可以将任何类型作为参数传递并返回任何类型。
无论如何,我正在传递一个对象,其中包含以下属性:
public byte[] Photo { get; set; }
为了启用大型消息,我想开始使用 Mtom,而我以前使用纯文本作为消息编码类型。
问题是,我希望它是向后兼容的,所以当前已经配置的客户端应该继续使用纯文本编码,而新客户端应该能够通过 web.config 使用 Mtom。
我的问题是:是否可以默认继续使用纯文本作为消息编码(现有客户端)并排提供 Mtom 编码?
我已经尝试了一些配置,例如使用不同的绑定配置定义多个端点,但我无法让它工作:
服务器
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpTextBinding_SocialProxy" />
<binding name="BasicHttpMtomBinding_SocialProxy" maxReceivedMessageSize="5242880" messageEncoding="Mtom">
<readerQuotas maxStringContentLength="655360" maxArrayLength="1310720" maxNameTableCharCount="1310720" maxBytesPerRead="327680" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="SocialProxyService">
<endpoint name="BasicEndpoint_SocialProxy" address="" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpTextBinding_SocialProxy" />
<endpoint name="MtomEndpoint_SocialProxy" address="" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpMtomBinding_SocialProxy" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
客户
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_SocialProxy" messageEncoding="Mtom" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://socialproxy.local/socialproxy.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SocialProxy"
contract="Webservice.SocialProxy" name="BasicHttpBinding_SocialProxy" />
</client>
</system.serviceModel>
问题是:
如果我不设置 Mtom 消息编码 @ 客户端,一切都通过纯文本工作。但是当我将其设置为使用 Mtom 时,我会得到一个异常:
The remote server returned an error: (415) Cannot process the message because the content type 'multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:65a6b418-8eb3-4c76-b4c0-ea3486a56892+id=2";start-info="text/xml"' was not the expected type 'text/xml; charset=utf-8'..
有人能帮助我吗? :-)
添加新终结点(对于较新的客户端),则该终结点需要位于不同的地址中。由于您没有收到任何错误,因此我想您在<service>
元素的name
属性中的名称不正确。请记住,name 属性应包含服务类的完全限定名称。如果您的服务类位于命名空间InfoCaster.SocialProxy
,则应按如下方式定义服务配置:
<services>
<service name="InfoCaster.SocialProxy.SocialProxyService">
<endpoint name="BasicEndpoint_SocialProxy" address="" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpTextBinding_SocialProxy" />
<endpoint name="MtomEndpoint_SocialProxy" address="newClients" contract="InfoCaster.SocialProxy.ISocialProxy" binding="basicHttpBinding" bindingConfiguration="BasicHttpMtomBinding_SocialProxy" />
</service>
</services>
客户会有类似的东西
<client>
<endpoint address="http://socialproxy.local/socialproxy.svc/newClients"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SocialProxy"
contract="Webservice.SocialProxy" name="BasicHttpBinding_SocialProxy" />
</client>
现在,如果您想要一个可以同时支持文本和 MTOM 的终结点,即发送文本的客户端接收文本响应,而发送 MTOM 的客户端接收返回的 MTOM 响应,您仍然可以这样做。你需要一个自定义编码器,我在 http://blogs.msdn.com/b/carlosfigueira/archive/2011/02/16/using-mtom-in-a-wcf-custom-encoder.aspx 的帖子中写了一个。