Заголовок мыла WSDL WCF на все операции - PullRequest
4 голосов
/ 12 июня 2009

Определив атрибут, который реализует IContactBehavior и IWsdlExportExtension и установив этот атрибут в контракте на обслуживание, вы можете легко добавить Заголовки мыла к вашему wsdl (см. http://wcfextras.codeplex.com/ для получения дополнительной информации)

Но теперь мне нужно установить контракт заголовка мыла в wsdl для всех операционных контрактов, и на этот раз я не могу установить атрибут.

Следующий код (вызывается из 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?

Ответы [ 3 ]

5 голосов
/ 15 июня 2009

IEndpointBehavior имеет следующий интерфейс:

ApplyDispatchBehavior(ServiceEndpoint endPoint, EndPointDispatcher endpointDispatcher);

Вы можете добавить заголовки мыла в wsdl для операций, перебирая конечную точку. Control.Operations в ApplyDispatchBehavior.

Вот вам полное решение, которое сработало для меня:

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 голосов
/ 12 июня 2009

Возможно, вы захотите взглянуть на проект WCFExtras в CodePlex - он имеет некоторую поддержку пользовательских заголовков SOAP и тому подобное. Не уверен на 100%, способен ли он удовлетворить ваши потребности, но зацените!

Марк

ОБНОВЛЕНИЕ: рассматривали ли вы создание расширения WCF, например, что-то вроде инспектора сообщений, как на стороне клиента, так и на стороне сервера?

Клиентская сторона IClientMessageInspector определяет два метода BeforeSendRequest и AfterReceiveReply, в то время как на стороне сервера IDispatchMessageInspector имеет противоположные методы, т.е.

При этом вы можете добавлять заголовки к каждому сообщению, передаваемому по сети (или выборочно только к нескольким).

Вот фрагмент кода от разработчика 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;
}
0 голосов
/ 28 мая 2014

Самый простой способ - использовать 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);
}

Тогда запрос на мыло выглядит так:

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

Если вам нужны Soap и JSON в одном сервисе, вот пример: https://stackoverflow.com/a/23910916/3667714

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...