【问题标题】:Add a header to a REST WCF request - EnvelopeNone does not support adding Message Headers exception向 REST WCF 请求添加标头 - EnvelopeNone 不支持添加消息标头异常
【发布时间】:2009-10-01 21:41:05
【问题描述】:

我正在尝试将自定义标头添加到访问标准 RESTful 端点的 wcf 客户端。我正在尝试添加某种标头,仅允许我跟踪从一层到下一层的请求。以下是我尝试实现它的方式:

public class DynatracePurePathHeaderAppender : IClientMessageInspector, IEndpointBehavior
 {
  object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
  {
   var dynaHeader = MessageHeader.CreateHeader("Action", "ns.yellowbook.jeff", "dynatrace",false);
   request.Headers.Add(dynaHeader);
   return null;
  }

  void IClientMessageInspector.AfterReceiveReply(ref Message reply, object correlationState)
  {
   return;
  }

  public void Validate(ServiceEndpoint endpoint){}

  public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){}

  public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher){}

  public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  {
   clientRuntime.MessageInspectors.Add(this);
  }
 }

public class DynatracePurePathHeaderAppenderElement : BehaviorExtensionElement
 {
  protected override object CreateBehavior()
  {
   return new DynatracePurePathHeaderAppender();
  }

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

然后我成功配置了客户端,但是当它运行时,我得到以下异常:

System.InvalidOperationException:信封版本'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)' 没有 支持添加消息头。

有人对如何插入这个小钡餐有任何建议吗?

【问题讨论】:

    标签: wcf rest header


    【解决方案1】:

    我假设您的意思是 HTTP 标头而不是 SOAP 标头?如果是这样,MessageHeader 与此无关。

    试试这样的:

    HttpRequestMessageProperty hrmp = new HttpRequestMessageProperty();
    //Set hrmp.Headers, then:
    request.Properties.Add(HttpRequestMessageProperty.Name, hrmp);
    

    一般来说,WCF REST 支持在客户端并没有真正优化(创建它主要是为了让人们创建 REST 服务)。要获得更好的客户端 REST 支持,请查看 WCF REST Starter Kit 中的 HttpClient。

    【讨论】:

      【解决方案2】:

      在方法 BeforeSendReply 中你需要得到响应:

      var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
      

      当您有响应实例时,您可以轻松添加所需的任何标题:

      httpHeader.Headers.Add("my Custom Header", "My Value");
      

      【讨论】:

        【解决方案3】:

        我知道这已经晚了,但我偶然发现了这篇文章,所以决定填写这个,以防我需要再次记住这一点。这对我有用:

        1. 创建消息检查器:

          Public Class AuthenticationHeader
            Implements IClientMessageInspector
          
          Private itsUser As String
          Private itsPass As String
          
          Public Sub New(ByVal user As String, ByVal pass As String)
              itsUser = user
              itsPass = pass
          End Sub
          
          Public Sub AfterReceiveReply(ByRef reply As Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply
              Console.WriteLine("Received the following reply: '{0}'", reply.ToString())
          End Sub
          
          Public Function BeforeSendRequest(ByRef request As Message, channel As IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest
              Dim hrmp As HttpRequestMessageProperty = request.Properties("httpRequest")
              Dim encoded As String = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(itsUser + ":" + itsPass))
              hrmp.Headers.Add("Authorization", "Basic " + encoded)
              Return request
            End Function
          End Class
          
        2. 编写行为:

          Public Class AuthenticationHeaderBehavior
          Implements IEndpointBehavior
          
          Private ReadOnly itsUser As String
          Private ReadOnly itsPass As String
          
          Public Sub New(ByVal user As String, ByVal pass As String)
              MyBase.New()
              itsUser = user
              itsPass = pass
          End Sub
          
          Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
          End Sub
          
          Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
              clientRuntime.MessageInspectors.Add(New AuthenticationHeader(itsUser, itsPass))
          End Sub
          
          Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
          End Sub
          
          Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
          End Sub
          End Class
          
        3. 将其添加到您的端点:

            Dim binding As New WebHttpBinding(WebHttpSecurityMode.Transport)
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
          
            ChlFactory = New WebChannelFactory(Of IMyServiceContract)(binding, New Uri(url))
            ChlFactory.Endpoint.Behaviors.Add(New WebHttpBehavior())
            ChlFactory.Endpoint.Behaviors.Add(New AuthenticationHeaderBehavior(user, pass))
            Channel = ChlFactory.CreateChannel()
          

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-22
          • 1970-01-01
          • 1970-01-01
          • 2012-12-01
          相关资源
          最近更新 更多