2013-04-04 95 views
2

我是WCF新手。我正在托管一个由第三方应用程序(TPA)调用的WCF服务。 TPA需要WCF服务响应,以自定义页眉和响应SOAP信封应该是这样的:如何在WCF服务响应中正确实现自定义soap 1.2头和WS-Addressing

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
       xmlns:stan="http://client/schema/framework/header/standardheaderresponse" 
       xmlns:sys="http://client/schema/framework/common/systemidentifier" > 

    <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> 
    <stan:StandardHeaderResponse> 
     <stan:From> 
     <sys:Identifier>BUS</sys:Identifier> 
     <sys:Name>BuildingEvent</sys:Name> 
     <sys:Version>1</sys:Version> 
     </stan:From> 
     <stan:Timestamp>2013-03-15T03:05:41.000</stan:Timestamp> 
     <stan:CorrelationID>uuid:c12c9e48-8164-4074-9c8c-2b979804dbd2</stan:CorrelationID> 
    </stan:StandardHeaderResponse> 

    <wsa:Action> 
     http://client/service.buildingloc.event.BuildingEvent.SendEvent 
    </wsa:Action> 
    <wsa:MessageID>uuid:ab4c4001-f089-721c-aae6-f51ec37d3501</wsa:MessageID> 
    <wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To> 
    <wsa:RelatesTo>uuid:de9a7007-f056-431c-aae6-f51ec37d3488</wsa:RelatesTo> 
    </soap:Header> 

    <soap:Body> 
    … 
    </soap:Body> 

</soap:Envelope> 

我的服务使用的是自定义WCF的结合如下:

var binding  = new CustomBinding(); 
binding.Elements.Add(new TextMessageEncodingBindingElement() { MessageVersion = MessageVersion.Soap12WSAddressing10 }); 
binding.Elements.Add(new HttpTransportBindingElement()); 

要添加自定义的SOAP头我的回应我使用的是IDispatchMessageInspector,它看起来如下:

public void BeforeSendReply(ref Message reply, object correlationState) 
     { 
      reply.Headers.Add(new StandardHeaderResponse()); 
     } 

和的MessageHeader如下:

[MessageContract] 
    public class StandardHeaderResponse : MessageHeader 
    { 
     #region Overrides of MessageHeaderInfo 

     public override string Name 
     { 
      get { return GetType().Name; } 
     } 

     public override string Namespace 
     { 
      get { return "client/schema/framework/header/standardheaderresponse"; } 
     } 

     #endregion 

     #region Overrides of MessageHeader 

     protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) 
     { 
      writer.WriteElementString("Key", "Value"); 
     } 

     #endregion 
    } 

但是当我运行的服务,并从我的测试客户端触发一个请求,我得到下面的输出提琴手

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing"> 
    <s:Header> 
    <a:RelatesTo>urn:uuid:953e0b5b-44c6-4994-aae2-7710c31cb8f0</a:RelatesTo> 
    <StandardHeaderResponse> 
     <Key>Value</Key> 
    </StandardHeaderResponse> 
    </s:Header> 
    <s:Body> 
    ... 
    </s:Body> 
</s:Envelope> 

这对TPA是如何期待它完全不同。我需要做些什么来使提琴手输出看起来更像TPA所期待的。为什么不将所有WS-Address元素(例如<wsa:Action>,<wsa:MessageID><wsa:RelatesTo>)都渲染为标题的一部分。任何帮助将非常感激。

回答

6

下面是一个例子。我使用适当的Namespaces和DataMembers创建了DataContract类。然后我已经将根类的实例添加到消息标题。为了填充WSA元素,我在Message.Headers集合上使用了属性。

class Program 
{ 
    [DataContract(Namespace = "http://client/schema/framework/header/standardheaderresponse")] 
    public class StandardHeaderResponse 
    { 
     [DataMember(Order = 1)] 
     public FromHeaderResponse From { get; set; } 

     [DataMember(Order = 2)] 
     public DateTime Timestamp { get; set; } 

     [DataMember(Order = 3)] 
     public Guid CorrelationID { get; set; } 
    } 

    [DataContract(Namespace = "http://client/schema/framework/common/systemidentifier")] 
    public class FromHeaderResponse 
    { 
     [DataMember(Order = 1)] 
     public string Identifier { get; set; } 

     [DataMember(Order = 2)] 
     public string Name { get; set; } 

     [DataMember(Order = 3)] 
     public int Version { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     Message message = Message.CreateMessage(MessageVersion.Default, "http://client/service.buildingloc.event.BuildingEvent.SendEvent", "Message body"); 

     var header = new StandardHeaderResponse() 
     { 
      CorrelationID = Guid.NewGuid(), 
      Timestamp = DateTime.Now, 
      From = new FromHeaderResponse() 
      { 
       Identifier = "BUS", 
       Name = "BuildingEvent", 
       Version = 1 
      } 
     }; 

     message.Headers.Add(MessageHeader.CreateHeader("StandardHeaderResponse", "http://client/schema/framework/header/standardheaderresponse", header)); 
     message.Headers.Action = @"http://client/service.buildingloc.event.BuildingEvent.SendEvent"; 
     message.Headers.To = new Uri(@"http://www.w3.org/2005/08/addressing/anonymous"); 
     message.Headers.MessageId = new System.Xml.UniqueId(Guid.NewGuid()); 
     message.Headers.RelatesTo = new System.Xml.UniqueId(Guid.NewGuid()); 

     Console.WriteLine(message.ToString()); 
     Console.WriteLine("Press any key to exit..."); 
     Console.ReadKey(); 
    } 
} 

结果消息看起来像:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
    <s:Header> 
    <a:Action s:mustUnderstand="1">http://client/service.buildingloc.event.BuildingEvent.SendEvent</a:Action> 
    <StandardHeaderResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://client/schema/framework/header/standardheaderresponse"> 
     <From xmlns:d4p1="http://client/schema/framework/common/systemidentifier"> 
     <d4p1:Identifier>BUS</d4p1:Identifier> 
     <d4p1:Name>BuildingEvent</d4p1:Name> 
     <d4p1:Version>1</d4p1:Version> 
     </From> 
     <Timestamp>2013-04-10T00:17:13.8001086+02:00</Timestamp> 
     <CorrelationID>6fa83bf3-95f2-4101-aa78-b271a9e96aae</CorrelationID> 
    </StandardHeaderResponse> 
    <a:To s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/anonymous</a:To> 
    <a:MessageID>urn:uuid:88bc7f91-1de6-4c08-84bc-de75e029337d</a:MessageID> 
    <a:RelatesTo>urn:uuid:6dd90731-5ca3-4c83-949b-194ee9da4b6c</a:RelatesTo> 
    </s:Header> 
    <s:Body> 
    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Message body</string> 
    </s:Body> 
</s:Envelope> 

它没有格式化完全一样,但它是相同的消息。

希望这会有所帮助。

+0

谢谢@Enes我会实施这个,看看它是否工作。 – Raghu 2013-04-10 07:13:33

相关问题