Пользовательские SOAP-заголовки WCF - PullRequest
1 голос
/ 02 марта 2010

Я пытаюсь реализовать поведение конечной точки, которое вставляет настраиваемый заголовок SOAP во все сообщения в службу и из службы. Я подошел довольно близко, реализовав подход из принятого ответа на этот вопрос:

WCF-заголовок мыла WSDL для всех операций

После реализации этого решения мой настраиваемый заголовок SOAP действительно появляется в WSDL; однако, когда я пытаюсь вызвать методы моего сервиса, я получаю следующее исключение / ошибку:

<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <HelpLink i:nil="true" />
      <InnerException i:nil="true" />
      <Message>Index was outside the bounds of the array.</Message>
      <StackTrace>   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.AddHeadersToMessage(Message message, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter.SerializeReply(MessageVersion messageVersion, Object[] parameters, Object result)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.SerializeOutputs(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace>
      <Type>System.IndexOutOfRangeException</Type>
    </ExceptionDetail>

Взгляд в Reflector на метод DataContractSerializerOperationFormatter.AddHeadersToMessage, который вызывает исключение, заставляет меня поверить, что следующий фрагмент вызывает проблему ... но я не уверен почему.

MessageHeaderDescription description = (MessageHeaderDescription) headerPart.Description;
object parameterValue = parameters[description.Index];

Я думаю, что последняя строка выше выдает исключение. Переменная parameters взята из IDispatchFormatter.SerializeReply

Что происходит?!? !!

Любая помощь будет принята с благодарностью ...

1 Ответ

0 голосов
/ 23 мая 2014

Я использовал тот же пример (« WCF-заголовок мыла WSDL для всех операций »), и произошла та же ошибка. Чтобы устранить эту ошибку, я удалил заголовок из запроса на доход, в функции «AfterReceiveRequest» в IDispatchMessageInspector. Я изменил пример так, чтобы заголовок добавлялся только к входящим сообщениям.

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

public class SoapHeaderEndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    #region BehaviorExtensionElement Members

    public override Type BehaviorType
    {
        get
        {
            return typeof(SoapHeaderEndpointBehavior);
        }
    }

    protected override object CreateBehavior()
    {
        return new SoapHeaderEndpointBehavior();
    }
    #endregion

    #region IEndpointBehavior Members

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        //throw new NotImplementedException();
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        var inspector = new FvsMessageInspector();
        clientRuntime.MessageInspectors.Add(inspector);
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        var channelDispatcher = endpointDispatcher.ChannelDispatcher;
        if (channelDispatcher == null)
            return;
        foreach (var ed in channelDispatcher.Endpoints)
        {
            var inspector = new FvsMessageInspector();
            ed.DispatchRuntime.MessageInspectors.Add(inspector);
        }

        foreach (OperationDescription operationDescription in endpoint.Contract.Operations)
        {
            string nmm = operationDescription.Name;
            foreach (MessageDescription msgDescription in operationDescription.Messages)
            {
                if (msgDescription.Direction == MessageDirection.Input)
                {
                    MessageHeaderDescription header = new MessageHeaderDescription("AuthHeader", "web");
                    header.Type = typeof(AuthHeader);
                    msgDescription.Headers.Add(header);
                }
            }
        }
    }

    public void Validate(ServiceEndpoint endpoint)
    {
        //throw new NotImplementedException();
    }

    #endregion
}

public class FvsMessageInspector : IDispatchMessageInspector, IClientMessageInspector
{
    #region IDispatchMessageInspector

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        int i = request.Headers.FindHeader("AuthHeader", "web");
        if (i >= 0)
        {
            AuthHeader header = request.Headers.GetHeader<AuthHeader>(i);
            //Use header info here
            request.Headers.RemoveAt(i);
        }
        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        //No need to do anything else
    }

    #endregion

    #region IClientMessageInspector

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        //No need to do anything else
    }

    #endregion
}

Но гораздо проще использовать WCFExtrasPlus: "https://wcfextrasplus.codeplex.com/wikipage?title=SOAP%20Headers&referringTitle=Documentation"

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