2009-06-12 77 views
4

通过定义一个实现IContactBehavior和IWsdlExportExtension和设置您的服务合同上属性的属性,你可以轻松地添加SOAP头到您的WSDL(见http://wcfextras.codeplex.com/了解更多信息)WCF WSDL SOAP消息头的所有操作

但是现在我需要在所有OperationContracts的wsdl中设置一个Soap Header合约,这次我不能设置属性。

下面的代码(从IWsdlExportExtension.ExportEndPoint调用)不起作用,但是从SoapHeaderAttributes(执行的IWsdlExportExtension.ExportContract)

foreach (OperationDescription operationDescription in context.ContractConversionContext.Contract.Operations) 
{ 
    AddSoapHeader(operationDescription, "SomeHeaderObject", typeof(SomeHeaderObject), SoapHeaderDirection.InOut);      
} 

internal static void AddSoapHeader(OperationDescription operationDescription, string name, Type type, SoapHeaderDirection direction) 
{ 
    MessageHeaderDescription header = GetMessageHeader(name, type); 
    bool input = ((direction & SoapHeaderDirection.In) == SoapHeaderDirection.In); 
    bool output = ((direction & SoapHeaderDirection.Out) == SoapHeaderDirection.Out); 

    foreach (MessageDescription msgDescription in operationDescription.Messages) 
    { 
     if ((msgDescription.Direction == MessageDirection.Input && input) || 
      (msgDescription.Direction == MessageDirection.Output && output)) 
      msgDescription.Headers.Add(header); 
    } 
} 

internal static MessageHeaderDescription GetMessageHeader(string name, Type type) 
{ 
    string headerNamespace = SoapHeaderHelper.GetNamespace(type); 
    MessageHeaderDescription messageHeaderDescription = new MessageHeaderDescription(name, headerNamespace); 
    messageHeaderDescription.Type = type; 
    return messageHeaderDescription; 
} 

任何人有一个想法如何使用这个代码调用时不工作在所有的操作(不使用属性),并通过这样做,将标题的合同添加到wsdl?

回答

5

该IEndpointBehavior具有以下接口:

ApplyDispatchBehavior(ServiceEndpoint endPoint, EndPointDispatcher endpointDispatcher); 

您可以通过迭代在ApplyDispatchBehavior的endpoint.Contract.Operations SOAP头添加到WSDL的操作。

在这里,你有一个为我工作的完整解决方案:

void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
{ 
    foreach (OperationDescription operationDescription in endpoint.Contract.Operations) 
    { 
     foreach (MessageDescription msgDescription in operationDescription.Messages) 
     { 
      AddSoapHeader(operationDescription, "SomeHeaderObject", typeof(SomeHeaderObject), SoapHeaderDirection.InOut); 
     } 
    } 
} 

internal static void AddSoapHeader(OperationDescription operationDescription, string name, Type type, SoapHeaderDirection direction) 
{ 
    MessageHeaderDescription header = GetMessageHeader(name, type); 
    bool input = ((direction & SoapHeaderDirection.In) == SoapHeaderDirection.In); 
    bool output = ((direction & SoapHeaderDirection.Out) == SoapHeaderDirection.Out); 

    foreach (MessageDescription msgDescription in operationDescription.Messages) 
    { 
      if ((msgDescription.Direction == MessageDirection.Input && input) || 
        (msgDescription.Direction == MessageDirection.Output && output)) 
        msgDescription.Headers.Add(header); 
    } 
} 

internal static MessageHeaderDescription GetMessageHeader(string name, Type type) 
{ 
    string headerNamespace = SoapHeaderHelper.GetNamespace(type); 
    MessageHeaderDescription messageHeaderDescription = new MessageHeaderDescription(name, headerNamespace); 
    messageHeaderDescription.Type = type; 
    return messageHeaderDescription; 
} 

的SoapHeaderHelper可以在WcfExtras找到。

4

您可能想看看CodePlex上的WCFExtras项目 - 它支持自定义SOAP头和类似的东西。不是100%确定它是否能够满足您的需求,但请检查一下!

马克

UPDATE:你看着创建一个WCF的扩展,例如就像消息检查器一样,在客户端和服务器端?

客户端侧IClientMessageInspector定义了两种方法BeforeSendRequestAfterReceiveReply而服务器侧IDispatchMessageInspector具有相反的方法,即AfterReceiveRequestBeforeSendReply

通过这种方式,您可以为穿过电线的每条消息添加标题(或仅选择性地添加到少数几个标题)。

下面是我们用来自动地传送从客户端到服务器的区域设置信息(语言和文化信息)跨IClientMessageInspector实施者的一个片段 - 应该给你一个想法如何开始:

public object BeforeSendRequest(ref Message request, IClientChannel channel) 
{ 
    International intlHeader = new International(); 
    intlHeader.Locale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; 

    MessageHeader header = MessageHeader.CreateHeader(WSI18N.ElementNames.International, WSI18N.NamespaceURI, intlHeader); 
    request.Headers.Add(header); 

    return null; 
} 
+1

我实际上指出WCFExtras我自己,但我无法找到如何添加肥皂头到t他在没有设置属性的情况下执行所有操作。 – Linefeed 2009-06-12 14:12:55

+0

我完全错过了你的链接wcf额外..... – 2009-06-12 14:49:42

0

最简单的方法是使用WCFExtrasPlus “https://wcfextrasplus.codeplex.com/wikipage?title=SOAP%20Headers&referringTitle=Documentation”,只需添加DLL作为参考到项目,并以这样一种方式修改您的服务:

[DataContract(Name="MyHeader", Namespace="web")] 
public class MyHeader 
{ 
    [DataMember(Order=1)] 
    public string UserName {get; set;} 
    [DataMember(Order=2)] 
    public string Password { get; set; } 
} 

[SoapHeaders] 
[ServiceContract] 
public interface IMyService 
{ 
    [SoapHeader("MyHeader", typeof(MyHeader), Direction = SoapHeaderDirection.In)] 
    [OperationContract] 
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped)] 
    bool MyMethod(string input); 
} 

然后SOAP请求的样子:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="web" xmlns:tem="http://tempuri.org/"> 
<soapenv:Header> 
    <web:MyHeader> 
    <web:UserName>?</web:UserName> 
    <web:Password>?</web:Password> 
    </web:MyHeader> 
</soapenv:Header> 
<soapenv:Body> 
    <tem:MyMethod> 
    <tem:input>?</tem:input> 
    </tem:MyMethod> 
</soapenv:Body> 
</soapenv:Envelope> 

如果你需要肥皂和JSON在相同的服务这里是例子:https://stackoverflow.com/a/23910916/3667714