在 C# 中为 SOAP 1.2 接受 text/xml

Accepting text/xml for SOAP 1.2 in C#

我有一个作为 SOAP API 运行的 .Net 3.5 WCF 服务。客户端现在需要发送 SOAP 1.2 信封(soap:Envelope 而不是 soapenv:Envelope),但他们仍然使用 text/xml 作为请求的内容类型而不是 application/soap+xml

是否可以通过配置调整服务以接受此行为,或者我是否需要创建类似 HttpHandler 的东西来拦截请求并修改内容类型?我已经在使用在 Dispatcher 中注册的自定义消息过滤器来满足对 Action 的修改,因为我正在阅读和路由自定义 header。

Web 服务的当前配置如下所示:

<services>
  <service behaviorConfiguration="Service1Behavior"
    name="BusinessService">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="myBindingForBigArrays"
      contract="IMasterService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>

    <endpoint address="/12" binding="customBinding" bindingConfiguration="https12Binding"
      contract="IMasterService" behaviorConfiguration="crsBehavior">

    </endpoint>
    <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
  </service>

绑定配置为

      <customBinding>
    <binding name="https12Binding">
      <transactionFlow />

      <textMessageEncoding messageVersion="Soap12">
        <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
            maxBytesPerRead="2147483647"
            maxNameTableCharCount="2147483647" />
      </textMessageEncoding>
      <httpsTransport maxReceivedMessageSize="2147483647"  />
    </binding>
  </customBinding>
  <basicHttpBinding>

    <binding name="myBindingForBigArrays" maxReceivedMessageSize="2147483647">
      <security mode="Transport">
        <transport clientCredentialType="None"/>
      </security>
      <readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    </binding>
  </basicHttpBinding>

我已经解决了我的问题,我将更新此问题以供将来参考以及可能遇到此问题的任何其他人。

这样做的诀窍是注册一个新的文本编码元素来标识此绑定可能接受的消息类型。

由于<textMessageEncoding />元素只能真正带SOAP11(text/xml)和SOAP12(application/soap+xml),注册一个新的可以配置的自定义元素更进一步是最可靠的方法。

Microsoft 有一些示例代码可以执行此操作,可以轻松将其导入到解决方案中(我创建了一个单独的库来存放此代码以供参考)。可以在此处找到此参考数据 here, and the sample code here

实施此代码后,您可以定义新的 textMessageEncoding 元素 customTextMessageEncoding 组合,例如 <customTextMessageEncoding encoding="utf-8" mediaType="text/xml" messageVersion="Soap12" />。请注意,引用 link 错误地将上面的行标记为 contentType 而不是 mediaType。上面的组合允许我使用 SOAP 1.2 信封和 SOAP 1.1 内容类型注册绑定。

另一件事是使用 mediaType 来更改响应类型,并覆盖 MessageEncoder 上的 IsContentTypeSupported 以允许服务响应不同的内容类型。这也是客户的要求,尽管它很不寻常。该服务现在可以接受 text/xml 和 application/soap+xml(通过覆盖的方法)并响应提供的 mediaType

简而言之,解决方案需要:

  1. 实施自定义编码器和编码器工厂
  2. 为自定义编码器实施绑定元素
  3. 使用自定义绑定配置集成自定义绑定元素
  4. 开发自定义配置处理程序以允许自定义绑定元素的文件配置(app.config 或 web.config)
  5. 在 web.config
  6. 中注册新的绑定元素
  7. 使用新的绑定元素配置绑定