【问题标题】:WCF Custom SOAP Header IssuesWCF 自定义 SOAP 标头问题
【发布时间】:2010-03-02 01:08:20
【问题描述】:

我正在尝试实现一个端点行为,它将自定义 SOAP 标头注入到服务的所有消息中。通过实施这个问题的公认答案中的方法,我已经非常接近了:

WCF WSDL Soap Header on all operations

实施该解决方案后,我的自定义 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>

在反射器中查看引发异常的 DataContractSerializerOperationFormatter.AddHeadersToMessage 方法,让我相信以下 sn-p 导致了问题......但我不确定为什么。

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

我认为上面的最后一行是抛出异常。 parameters 变量来自IDispatchFormatter.SerializeReply

这是怎么回事?!?!!

任何帮助将不胜感激...

【问题讨论】:

  • description.Index 的值究竟是什么?是-1吗?
  • 我无法调试到 DataContractSerializerOperationFormatter.AddHeadersToMessage 方法,但我注入的 MessageHeaderDescription 对象的索引值都为零。我想如果parameters 为空或零长度,这会抛出该异常,但我无法控制该变量(我不认为)

标签: wcf soap wsdl


【解决方案1】:

我使用了相同的示例(“WCF WSDL Soap Header on all operations”),并且出现了相同的错误。为了解决这个错误,我在 IDispatchMessageInspector 的函数“AfterReceiveRequest”中删除了收入请求中的标头。我已经修改了示例,将标头仅添加到传入的消息中。

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

【讨论】:

    【解决方案2】:

    我发现使用 IContractBehaviorIWsdlExportExtension 修改导出的合同可以正常工作,并且不需要重写任何消息(就像在其他列出的答案中一样),而不是使用 IServiceBehavior 修改合同。

    【讨论】:

      猜你喜欢
      • 2011-01-04
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 2014-02-25
      • 1970-01-01
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多