为 WCF 消息设置 HTTP content-type
Setting HTTP content-type for WCF message
我正在使用外部 SOAP 服务,即欧洲国家药品验证系统,我无法控制它。我的应用程序使用从提供的 WSDL 自动生成的 WCF 客户端。客户端使用 System.ServiceModel.Channels.Message 条消息。
SOAP 服务对 G482LoadTermsAndConditions 和 G487LoadDataPrivacyPolicies 两个消息使用相同的消息结构,即“I7RequestType”,并且不“理解”任何操作 header。
这是我的请求消息,带有被忽略的操作 header :
<?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 操作,如果 mustUnderstand 设置为 1,则 returns 错误。
显然我应该使用 HTTP content-type 来允许服务器区分这两个消息。这是我得到的例子:
Content-Type : application/soap+xml;charset=utf-8;method=SUPPORT-I7RequestType;action="urn:G482LoadTermsAndConditions";
我的自定义 MessageInspector 可以在 BeforeSendRequest() 中操作消息内容,但我找不到任何方法 adding/modifying 封装 HTTP 消息的 headers。
有人知道修改出站 System.ServiceModel.Channels.Message 的 HTTP header 的方法吗?
提前致谢。
经过大量搜索,问题似乎是由于生成的 WCF 客户端不符合 WSDL 和 SOAP 1.2 规范。
这个答案 为我提供了创建解决方法所需的一切。
这是硬编码的概念验证代码,很大程度上基于 Dejan Janjušević 的回复,我在我的 CustomMessageInspector(实现 IEndpointBehavior 和 IClientMessageInspector)的函数 BeforeSendRequest() 中添加了它。
// 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\"" );
我正在使用外部 SOAP 服务,即欧洲国家药品验证系统,我无法控制它。我的应用程序使用从提供的 WSDL 自动生成的 WCF 客户端。客户端使用 System.ServiceModel.Channels.Message 条消息。
SOAP 服务对 G482LoadTermsAndConditions 和 G487LoadDataPrivacyPolicies 两个消息使用相同的消息结构,即“I7RequestType”,并且不“理解”任何操作 header。
这是我的请求消息,带有被忽略的操作 header :
<?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 操作,如果 mustUnderstand 设置为 1,则 returns 错误。
显然我应该使用 HTTP content-type 来允许服务器区分这两个消息。这是我得到的例子:
Content-Type : application/soap+xml;charset=utf-8;method=SUPPORT-I7RequestType;action="urn:G482LoadTermsAndConditions";
我的自定义 MessageInspector 可以在 BeforeSendRequest() 中操作消息内容,但我找不到任何方法 adding/modifying 封装 HTTP 消息的 headers。
有人知道修改出站 System.ServiceModel.Channels.Message 的 HTTP header 的方法吗?
提前致谢。
经过大量搜索,问题似乎是由于生成的 WCF 客户端不符合 WSDL 和 SOAP 1.2 规范。
这个答案 为我提供了创建解决方法所需的一切。
这是硬编码的概念验证代码,很大程度上基于 Dejan Janjušević 的回复,我在我的 CustomMessageInspector(实现 IEndpointBehavior 和 IClientMessageInspector)的函数 BeforeSendRequest() 中添加了它。
// 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\"" );