为 WCF 消息设置 HTTP 内容类型

Posted

技术标签:

【中文标题】为 WCF 消息设置 HTTP 内容类型【英文标题】:Setting HTTP content-type for WCF message 【发布时间】:2021-10-21 00:24:11 【问题描述】:

我正在使用外部 SOAP 服务,即欧洲国家药品验证系统,对此我无法控制。我的应用程序使用从提供的 WSDL 自动生成的 WCF 客户端。客户端使用 System.ServiceModel.Channels.Message 消息。

SOAP 服务对 2 条消息(G482LoadTermsAndConditions 和 G487LoadDataPrivacyPolicies)使用相同的消息结构“I7RequestType”,并且不“理解”任何 Action 标头。

这是我的请求消息,带有忽略的 Action 标头:

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
   <s:Header>
      <a:Action s:mustUnderstand="0">ns:G482RequestMessage</a:Action>
   </s:Header>
   <s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <I7RequestType xmlns="urn:wsdltypes.nmvs.eu:v4.0">
         <Header xmlns="urn:types.nmvs.eu:v4.0">
            <Auth>
               <ClientLoginId>xxxxx</ClientLoginId>
               <UserId>xxxxx</UserId>
               <Password>xxxxx</Password>
            </Auth>
            <UserSoftware xmlns:d5p1="urn:types.nmvs.eu:v4.0" d5p1:name="xxxxx" d5p1:supplier="xxxxx" d5p1:version="2.0" />
            <Transaction>
               <ClientTrxId>xxxxxxxxxxxxxxx</ClientTrxId>
               <Language>fra</Language>
            </Transaction>
         </Header>
      </I7RequestType>
   </s:Body>
</s:Envelope>

Header Action 被服务器忽略,如果 mustUnderstand 设置为 1,则返回错误。

显然我应该使用 HTTP 内容类型来允许服务器区分这两个消息。这是我得到的例子:

    Content-Type : application/soap+xml;charset=utf-8;method=SUPPORT-I7RequestType;action="urn:G482LoadTermsAndConditions"; 

我的自定义 MessageInspector 可以在 BeforeSendRequest() 中操作消息内容,但我找不到任何添加/修改封装 HTTP 消息标头的方法。

有人知道修改出站 System.ServiceModel.Channels.Message 的 HTTP 标头的任何方法吗?

提前致谢。

【问题讨论】:

您可以在此链接中查看已接受的答案:Create a custom IIdentity in WCF REST when binding security is TransportCredentialOnly 【参考方案1】:

经过大量搜索,问题似乎是由于生成的 WCF 客户端不遵守 WSDL 和 SOAP 1.2 规范。

WCF Service with wsHttpBinding - Manipulating HTTP request headers 这个答案为我提供了创建解决方法所需的一切。

这是硬编码的概念验证代码,很大程度上基于 Dejan Janjušević 的回复,我在 CustomMessageInspector 的函数 BeforeSendRequest() 中添加了该代码(实现 IEndpointBehavior 和 IClientMessageInspector)。

        // Making sure we have a HttpRequestMessageProperty
        HttpRequestMessageProperty httpRequestMessageProperty;
        if( request.Properties.ContainsKey( HttpRequestMessageProperty.Name ) )
        
            httpRequestMessageProperty = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
            if( httpRequestMessageProperty == null )
            
                httpRequestMessageProperty = new HttpRequestMessageProperty();
                request.Properties.Add( HttpRequestMessageProperty.Name, httpRequestMessageProperty );
            
        
        else
        
            httpRequestMessageProperty = new HttpRequestMessageProperty();
            request.Properties.Add( HttpRequestMessageProperty.Name, httpRequestMessageProperty );
        

        Console.WriteLine("original Request:");
        Console.WriteLine("0\r\n", request);
        request.Headers.Clear();

        httpRequestMessageProperty.Headers.Add( "Content-Type", "application/soap+xml;charset=utf-8;method=SUPPORT-I7RequestType;action=\"urn:G482LoadTermsAndConditions\"" );

【讨论】:

以上是关于为 WCF 消息设置 HTTP 内容类型的主要内容,如果未能解决你的问题,请参考以下文章

WCF服务客户端:内容类型text/html;响应消息的charset=utf-8 与绑定的内容类型不匹配

响应消息的内容类型application/xml;charset=utf-8 与绑定的内容类型(text/xml;charset=utf-8)不匹配,WCF

我可以在不设置内容类型的情况下调用 WCF 服务吗?

Wcf 服务,我收到此错误:内容类型 text/html;字符集=utf-8

从 BizTalk WCF-WebHttp 适配器向 Mule 服务发布消息时出错:服务不支持内容类型应用程序/json

WCF:具有不同内容类型的请求/响应