2010-03-02 98 views
1

我试图实现一个端点行为,它将一个自定义SOAP头插入所有发往和来自服务的消息中。我已经得到了通过实现从这个问题的答案接受的做法相当接近:WCF自定义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方法多数民众赞成抛出异常,使我相信,下面的代码片段造成这个问题...但我不知道为什么。

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

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

发生了什么?!?!!

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

+0

到底是什么description.Index的价值?是-1吗? – jrista 2010-03-02 06:09:42

+0

我无法调试到DataContractSerializerOperationFormatter.AddHeadersToMessage方法,但我注入的MessageHeaderDescription对象都有一个索引值为零。我想这会抛出这个异常,如果'parameters'为null或零长度,但我没有控制该变量(我不认为) – WayneC 2010-03-02 21:48:42

回答

0

我已经使用了相同的例子(“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 
} 

但大部分simpliers的aproach是使用WCFExtrasPlus: “https://wcfextrasplus.codeplex.com/wikipage?title=SOAP%20Headers&referringTitle=Documentation