如何将WS-Addressing字段添加到SOAP消息中



我在项目中创建了一个指向web服务的链接(即添加服务参考->高级->添加web服务参考)。

VS生成了一个代理类:System.Web.Services.Protocols.SoapHttpClientProtocol

WSDL看起来像:

<definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
<types>
<xsd:schema ... >
<xsd:include schemaLocation="https://server.com/path/path/Serv?xsd=../path/path/path/name.xsd"/>
... 
</xsd:schema>
</types>
<message name="Mes1_Message">
<part element="..." name="body"></part>
</message>
... 
<message>...</message>
<portType name="name">
<operation name="Method1">
<input message="name" wsaw:Action="name"></input>
<output message="name" wsaw:Action="name"></output>
</operation>
... 
</operation>

<binding name="name" type="type">
<soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsaw:UsingAddressing xmlns:ns3="http://schemas.xmlsoap.org/wsdl/" required="true"/>
<wsaw:Anonymous>required</wsaw:Anonymous>
<operation name="Method1">...</operation>
<operation name="Method2">...</operation>
<service name="name">
<port binding="tns:name" name="name">
<soap12:address location="https://server.com/Serv"/>
</port>
</service>
</definitions>

如何向SOAP请求添加一些强制数据?

<wsa:MessageID> ...</wsa:MessageID>
<wsa:ReplyTo> <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address></wsa:ReplyTo>
<wsa:Action>...</wsa:Action>
<wsa:To>...</wsa:To>
<wsa:RelatesTo></wsa:RelatesTo>

您的解决方案应该包括以下四个步骤:

a) 为每个WS-Addressing字段定义类,如:

public class AddressingHeader : SoapHeader
{
    public AddressingHeader()
        : base() { }
    [XmlElement("Action")]
    public string Action
    {
        get; set;
    }
}

b) 定义一个Soap扩展,将这些头添加到Soap信封:

public class AddressingExtension : SoapExtension
{
    public AddressingExtension()
        : base() { }
    public override object GetInitializer(Type serviceType)
    {
        return null;
    }
    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return null;
    }
    public override void Initialize(object initializer)
    {
    }
    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                AddAddressingHeaders(message);
                break;
            default:
                break;
        }
    }
    private void AddAddressingHeaders(SoapMessage message)
    {
        message.Headers.Add(new AddressingHeader());           
    }
}

c) 定义一个Soap扩展属性来标记您选择的web方法:

[AttributeUsage(AttributeTargets.Method)]
public class AddressingExtensionAttribute : SoapExtensionAttribute
{
    private string action;
    private int priority;
    public AddressingExtensionAttribute()
        : base()
    {
        this.action = "defaultaction";
    }
    public override Type ExtensionType
    {
        get
        {
            return typeof(AddressingExtension);
        }
    }
    public override int Priority
    {
        get
        {
            return priority;
        }
        set
        {
            priority = value;
        }
    }
    public string Action
    {
        get
        {
            return action;
        }
        set
        {
            action = value;
        }
    }
}

d) 不幸的是,您将不得不修改自动生成的代理类,以使用上述属性,例如:

    [System.Web.Services.Protocols.SoapDocumentMethodAttribute(...)]
    [WebApplication1.AddressingExtension(Action = "http://some.example/DoWork")]
    public void DoWork(...) {
        ...
    }

最新更新