我是一名WCF新手。我正在托管一个由第三方应用程序(TPA)调用的WCF服务。 TPA要求wcf服务响应具有自定义标头,响应soap信封应如下所示:
<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
}
但是当我运行服务并从我的测试客户端发出请求时,我在Fiddler中获得以下输出
<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>
都不会呈现为标题的一部分。任何帮助将不胜感激。
答案 0 :(得分:6)
这是一个例子。我已经使用适当的命名空间和DataMembers创建了DataContract类。然后我将根类的实例添加到Message Header。为了填充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>
它的格式不完全相同,但它是相同的消息。
希望这有帮助。