在ws-addressing规范中说:
2.2。端点参考XML信息集表示
/ WSA:EndpointReference的/ {任何}。 这是一种可扩展性机制,允许指定其他元素。
请告诉我如何构建这样的XML结构:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:ehkz="https://oag1.dev.mysite.org:11443/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<s:Header>
<ActivityId CorrelationId="114c74b1-3aaf-44c0-9d35-a9479fb9b60a" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">00000000-0000-0000-0000-000000000000</ActivityId>
<wsa:Action s:mustUnderstand="true">OrganizationQueryRequest</wsa:Action>
<wsa:MessageID>urn:uuid:a3539897-fc69-4adf-9ae4-1419ccbd7017</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:From s:mustUnderstand="true">
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
<ehkz:organizationID>1.2.398.7.1.9.3.2</ehkz:organizationID>
<ehkz:applicationID>1.2.398.7.1.5.1.14</ehkz:applicationID>
</wsa:From>
<wsa:To s:mustUnderstand="true">https://oag2.dev.mysite.org:11443/Organization</wsa:To>
</s:Header>
<s:Body> ... </s:Body>
</s:Envelope>
从元素感兴趣:
<wsa:From s:mustUnderstand="true">
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
<ehkz:organizationID>1.2.398.7.1.9.3.2</ehkz:organizationID>
<ehkz:applicationID>1.2.398.7.1.5.1.14</ehkz:applicationID>
</wsa:From>
当我尝试重复此操作时,我得到以下结构:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<ActivityId CorrelationId="594fce7f-a69c-4e9c-aabf-1af8de2fe1fd" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">e2d92b9e-4b56-45ea-b6f7-2d7cf0585f6e</ActivityId>
<a:Action s:mustUnderstand="1">HCProfessionalQueryRequest</a:Action>
<a:MessageID>urn:uuid:4e9a056f-5c91-42fb-bf04-4ba4bff5907b</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:From>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
<a:ReferenceParameters>
<organizationID xmlns="https://oag1.dev.mysite.org:11443/addressing">1.2.398.7.1.9.3.2</organizationID>
<applicationID xmlns="https://oag1.dev.mysite.org:11443/addressing">1.2.398.7.1.9.1.25</applicationID>
</a:ReferenceParameters>
</a:From>
<a:To s:mustUnderstand="1">https://oag2.dev.mysite.org:11443/Professional</a:To>
</s:Header>
<s:Body> ... </s:Body>
</s:Envelope>
元素来自看起来像这样:
<a:From>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
<a:ReferenceParameters>
<organizationID xmlns="https://oag1.dev.mysite.org:11443/addressing">1.2.398.7.1.9.3.2</organizationID>
<applicationID xmlns="https://oag1.dev.mysite.org:11443/addressing">1.2.398.7.1.9.1.25</applicationID>
</a:ReferenceParameters>
</a:From>
我的其他元素位于参考参数
下如何使applicationID和organizationID不能放在ReferenceProperty或ReferenceParameter元素中,而是直接放在WS寻址头的From元素中
这是我的代码:
public class SoapHeaderMessageInspector : IClientMessageInspector
{
private readonly string _applicationId;
private readonly string _organizationId;
private readonly string _soapAction;
public SoapHeaderMessageInspector(string applicationId, string organizationId, string soapAction = null)
{
_applicationId = applicationId;
_organizationId = organizationId;
_soapAction = soapAction;
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (request.Version != MessageVersion.Soap11 && request.Version != MessageVersion.Soap12)
{
var builder = new EndpointAddressBuilder(new EndpointAddress("http://www.w3.org/2005/08/addressing/anonymous"));
builder.Headers.Add(AddressHeader.CreateAddressHeader("organizationID", "https://oag1.dev.mysite.org:11443/addressing", _organizationId));
builder.Headers.Add(AddressHeader.CreateAddressHeader("applicationID", "https://oag1.dev.mysite.org:11443/addressing", _applicationId));
request.Headers.From = builder.ToEndpointAddress();
}
else
{
request.Headers.Add(MessageHeader.CreateHeader("organizationID", "https://oag1.dev.mysite.org:11443/addressing", _organizationId, false));
request.Headers.Add(MessageHeader.CreateHeader("applicationID", "https://oag1.dev.mysite.org:11443/addressing", _applicationId, false));
}
if (!string.IsNullOrEmpty(_soapAction))
request.Headers.Action = _soapAction;
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
}
在web.config中:
<binding name="Custom_Binding_Default">
<textMessageEncoding messageVersion="Default" />
<httpsTransport maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000" maxBufferSize="20000000" />
</binding>
<endpoint address="https://oag2.dev.mysite.org:11443/Organization"
binding="customBinding" bindingConfiguration="Custom_Binding_Default"
contract="OrganizationRegistryFeed" name="OrganizationDirectory_Port_Soap" />
答案 0 :(得分:0)
我知道这个答案可能晚了,但是我遇到了同样的问题,并且能够通过使用继承MessageHeader的类来解决它:
#ifndef GRANDPARENT_H
#define GRANDPARENT_H
struct foo {
int member;
};
#endif /* GRANDPARENT_H */
然后在您的IClientMessageInspector(SoapHeaderMessageInspector)中:
public class CustomMessageHeader : MessageHeader
{
private string _Name;
private string _NameSpace;
private object _Value;
private bool _IsReference;
private string _WsAddressElement;
private const string _WsAddressNamespace = "http://www.w3.org/2005/08/addressing";
public CustomMessageHeader(string name, string nameSpace, bool isReference, object value, string wsAdressElement = null)
{
_Name = name;
_NameSpace = nameSpace;
_Value = value;
_IsReference = isReference;
_WsAddressElement = wsAdressElement;
}
public override string Name
{
get
{
return _Name;
}
}
public override string Namespace
{
get
{
return _NameSpace;
}
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
if (!string.IsNullOrEmpty(_WsAddressElement))
writer.WriteStartElement(_WsAddressElement, _WsAddressNamespace);
if (_IsReference)
writer.WriteStartElement("ReferenceProperties", _WsAddressNamespace);
writer.WriteStartElement(_Name, _NameSpace);
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteValue(_Value);
if (_IsReference)
writer.WriteEndElement();
if (!string.IsNullOrEmpty(_WsAddressElement))
writer.WriteEndElement();
}
}
这将导致您的消息输出为:
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var fromMessageHeader = new CustomMessageHeader("organizationId", "https://oag1.dev.mysite.org:11443/addressing", true, _organizationId, "From");
request.Headers.Add(fromMessageHeader);
}
但这不是完整的解决方案,并且由于您需要多个ReferenceProperty以及正式的AddressHeader,因此您可能可以继承AddressHeader类并实现以下方法:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<ActivityId CorrelationId="594fce7f-a69c-4e9c-aabf-1af8de2fe1fd" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">e2d92b9e-4b56-45ea-b6f7-2d7cf0585f6e</ActivityId>
<a:Action s:mustUnderstand="1">HCProfessionalQueryRequest</a:Action>
<a:MessageID>urn:uuid:4e9a056f-5c91-42fb-bf04-4ba4bff5907b</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:From>
<a:ReferenceProperties>
<organizationID xmlns="https://oag1.dev.mysite.org:11443/addressing">1.2.398.7.1.9.3.2</organizationID>
</a:ReferenceProperties>
</a:From>
<a:To s:mustUnderstand="1">https://oag2.dev.mysite.org:11443/Professional</a:To>
</s:Header>
<s:Body> ... </s:Body>
</s:Envelope>
我希望这可以帮助将来寻求类似解决方案的人。