Asp.net 在WCF中支持Mtom和文本作为消息编码

Asp.net 在WCF中支持Mtom和文本作为消息编码,asp.net,wcf,iis,wcf-binding,mtom,Asp.net,Wcf,Iis,Wcf Binding,Mtom,我有一个WCF服务,它有一个具有以下签名的方法: object GetCommand(Guid apiKey, SocialService service, string name, object argument); 它使用对象作为返回类型和最后一个参数的原因是,它应该可以将任何类型作为参数传递并返回任何类型 无论如何,我正在传递一个对象,该对象包含以下属性: public byte[] Photo { get; set; } 为了启用大型消息,我想开始使用Mtom,而我以前使用纯文本作为

我有一个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 messageEncoding,那么一切都是通过纯文本进行的。但当我将其设置为使用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'..
远程服务器返回错误:(415)无法处理消息,因为内容类型为“多部分/相关”;type=“应用程序/xop+xml”;start=“”;边界=“uuid:65a6b418-8eb3-4c76-b4c0-ea3486a56892+id=2”;start info=“text/xml”不是预期的类型“text/xml”;字符集=utf-8'。。

有人能帮我吗?:-)

如果要添加新端点(对于较新的客户端),则该端点需要位于不同的地址中。由于您没有收到任何错误,我猜想您在
元素的
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响应,那么您仍然可以这样做。您需要一个自定义编码器,我在上的帖子中写了一个。

谢谢您的回复。如果我理解正确,就不可能为同一地址支持两种编码类型?那真是太遗憾了!明天我会尝试你的解决方案,完成后再发回来。你可以,但这不是那么简单。我已经用更多的细节更新了答案。非常感谢卡洛斯!当涉及到WCF和自定义消息编码器时,我有点不在行。问题是;我已经从你的博客中获取了代码片段,但是我仍然缺少一些部分。我还发现了这个论坛帖子;这里提到了一个c#文件,但它不可用。因此,当前的问题是实现ContentType、MediaType和MessageVersion属性。我还缺少一个名为“TextOrMtomEncodingBindingElement”的类。代码是这样的:天哪,我刚刚在你的博文底部看到了源代码的链接,我现在就去查看:-)所以在深入研究之后,我终于让它工作了。非常感谢卡洛斯!:-)