代码之家  ›  专栏  ›  技术社区  ›  WayneC

WCF自定义SOAP头问题

  •  1
  • WayneC  · 技术社区  · 15 年前

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

    WCF WSDL Soap Header on all operations

    <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 回复  |  直到 7 年前
        1
  •  0
  •   Community CDub    7 年前

    我用了同样的例子(” 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
    }
    

    https://wcfextrasplus.codeplex.com/wikipage?title=SOAP%20Headers&referringTitle=Documentation