【问题标题】:How to add additional elements in EndpointReferenceType (ws-addressing message information headers)如何在 EndpointReferenceType 中添加附加元素(ws-addressing 消息信息标头)
【发布时间】:2017-10-31 13:00:51
【问题描述】:

ws-addressing 规范中说:

2.2。端点引用 XML 信息集表示

/wsa:EndpointReference/{any}。 这是一种允许指定附加元素的扩展机制

请告诉我如何构建这样一个 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>

From 元素很有趣:

<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>

元素 From 看起来像这样:

<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>

我的附加元素放在 ReferenceParameters

如何使 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" />

【问题讨论】:

    标签: c# web-services wcf request-headers ws-addressing


    【解决方案1】:

    我知道这个答案可能很晚,但我遇到了同样的问题,并且能够通过使用继承 MessageHeader 的类来解决它:

    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();
        }
    
    }
    

    然后在你的 IClientMessageInspector (SoapHeaderMessageInspector) 中:

    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);
    }
    

    这将导致您的消息输出为:

    <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>
    

    但这不是完整的解决方案,因为您的要求是多个 ReferenceProperties 以及正式的 AddressHeader,您可以继承 AddressHeader 类并实现以下方法:

    protected abstract void OnWriteAddressHeaderContents(XmlDictionaryWriter writer);
    
    protected virtual void OnWriteStartAddressHeader(XmlDictionaryWriter writer);
    

    我希望这对将来寻找类似解决方案的人有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 2011-12-05
      • 2012-11-02
      相关资源
      最近更新 更多