【问题标题】:Supporting both Mtom and Text as MessageEncoding in WCF在 WCF 中同时支持 Mtom 和 Text 作为 MessageEncoding
【发布时间】:2012-04-25 02:42:12
【问题描述】:

我有一个 WCF 服务,它有一个带有以下签名的方法:

object GetCommand(Guid apiKey, SocialService service, string name, object argument);

它使用对象作为返回类型和最后一个参数的原因是因为它应该可以将任何类型作为参数传递并返回任何类型。

无论如何,我正在传递一个对象,其中包含以下属性:

public byte[] Photo { get; set; }

为了启用大消息,我想开始使用 Mtom,而我之前使用纯文本作为 MessageEncoding 类型。

问题是,我希望它向后兼容,因此当前已经配置的客户端应该继续使用纯文本编码,而新客户端应该能够通过 web.config 使用 Mtom。

我的问题是:是否可以在默认情况下继续使用纯文本作为 MessageEncoding(现有客户端)并同时提供 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'..

谁能帮帮我? :-)

【问题讨论】:

    标签: asp.net wcf iis wcf-binding mtom


    【解决方案1】:

    如果您想添加一个新端点(对于较新的客户端),该端点需要位于不同的地址。由于您没有收到任何错误,我想您在 &lt;service&gt; 元素的 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 的帖子中写了一个。

    【讨论】:

    • 感谢您的回复。如果我理解正确,是不可能支持同一地址的两种编码类型?那将是一个真正的遗憾!明天我会试试你的解决方案,完成后回复。
    • 你可以,但不是那么简单。我已经用更多细节更新了答案。
    • 非常感谢卡洛斯!当谈到 WCF 和自定义消息编码器时,我是一个菜鸟。问题是;我已经从您的博文中获取了代码片段,但我仍然缺少一些部分。我也找到了这个论坛帖子; social.msdn.microsoft.com/Forums/en-US/wcf/thread/… 并且那里提到了一个 c# 文件,但它不可用。所以我目前遇到的问题是实现 ContentType、MediaType 和 MessageVersion 属性。我还缺少一个名为“TextOrMtomEncodingBindingElement”的类。这是代码:pastebin.com/jxk3WeJX
    • 天啊,我刚刚在您的博文底部看到了指向源代码的链接,现在就去看看 :-)
    • 所以在挖掘了很多之后,我终于让它工作了。非常感谢卡洛斯! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2010-12-16
    相关资源
    最近更新 更多