【问题标题】:WCF Behavior Extension to BizTalk WCF-WebHttp Send Port not populating Date Http HeaderBizTalk WCF-WebHttp 发送端口的 WCF 行为扩展未填充日期 Http 标头
【发布时间】:2015-07-09 17:18:00
【问题描述】:

我有一个 BizTalk 2013 应用程序(不是 R2),它需要将 Json 文档发送到外部供应商的 RESTful api。供应商需要三个 Http 标头:

  1. 内容类型:application/json

  2. 日期:采用 ISO8601 UTC 格式

  3. 授权:自定义身份验证。使用包含上述日期值的构造字符串通过 HMACSHA1 哈希运行

在 BizTalk 中,我的出站 (xml) 消息发送到发送端口,有一个自定义管道组件使用 JSON.Net 转换为 Json。到目前为止,一切都很好。为了添加每条消息唯一的标头,我创建了一个实现 IClientInspector 和 IEndpointBehavior 的 WCF 行为扩展。在 BeforeSendRequest() 中,我获得了对请求的 HttpRequestMessageProperty 的引用。

我可以成功地向 Headers Collection 添加 ContentType 标头和 Authorization 标头。我无法添加 Date 标头 - 没有错误,只是在使用 Fiddler 检查时没有标头值。

我在某处读到 Date 是一个受限制的标题,对于一种解决方法,我可以使用 Reflection 来解决它。例如

    MethodInfo priMethod = headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic);
    priMethod.Invoke(headers, new[] { "Date", ISODateTimestamp });

那也没用。我真的很困惑: 1. 为什么我的请求中根本没有 Date 标头? 2.如果有的话,我怎么能操纵它,因为我需要给它是“受限的”?

我尝试了两个不同的选项:WCF 行为扩展:

public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
  {
      System.Diagnostics.Debug.Print("Entering BeforeSendRequest()");

      try
      {
          HttpRequestMessageProperty httpRequest = null;

          if (request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
          {
              httpRequest = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
          }

          WebHeaderCollection headers = httpRequest.Headers;

          headers.Add(HttpRequestHeader.ContentType, "application/json");
          headers.Add(string.Format("{0}:{1}", "Date", _taxwareHelper.ISODateTimestamp));
          headers.Add("tweDate", _taxwareHelper.ISODateTimestamp);
          headers.Add(HttpRequestHeader.Authorization, _taxwareHelper.AuthorizationString);

和发送管道中的自定义管道组件

string httpHeaderValue =
    new StringBuilder()
    .Append("Content-Type: application/json")
    .Append("\n")
    //.Append(string.Format("Date:{0}", taxwareHelper.ISODateTimestamp))
    //.Append("\n")
    .Append(string.Format("Date:{0}", "Fri, 10 Jul 2015 08:12:31 GMT"))
    .Append("\n")
    .Append(string.Format("tweDate:{0}", taxwareHelper.ISODateTimestamp))
    .Append("\n")
    .Append(string.Format("Authorization:{0}", taxwareHelper.AuthorizationString))
    .ToString();

pInMsg.Context.Write("HttpHeaders", "http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties", httpHeaderValue);

在任何一种情况下,我都可以设置 Content-Type、授权和测试日期 - tweDate 只是为了测试,但我不能设置实际的 Date 标头。

【问题讨论】:

  • 你使用的代码是什么?
  • 编辑了原始帖子以显示两种不同的尝试 - 自定义管道组件和 WCF 行为扩展。

标签: json wcf http-headers biztalk wcf-behaviour


【解决方案1】:

是的,确实 Date 是一个特殊的 HTTP 标头,它表示消息产生的日期和时间,但这并不妨碍您使用它。但日期必须采用 RFC 822 格式 Tue, 15 Nov 1994 08:12:31 GMT
另一件事是为什么你通过编写行为来让它变得困难,而你可以使用 HTTPHeaders 在你的自定义管道组件中添加你的自定义标头,而且这样更干净

因此请尝试以正确的格式转换您的日期或使用 HTTPHeaders

http://www.codit.eu/blog/2013/04/30/using-httpheaders-with-wcf-webhttp-adapter-on-biztalk-2013/ http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

【讨论】:

  • 谢谢。因为每条消息的标头值都是唯一的——授权键对于每条消息都是唯一的——我认为我不能使用发送管道组件,因为它是如何实例化的。这就是我选择 Wcf 行为扩展的原因。我也知道日期的格式要求,但 API 要求其他格式。我的主要问题是为什么我不能设置那个日期并在 Fiddler 中看到它。
  • 有许多受系统保护的标头,例如日期、主机,请检查您的日志,我打赌您会在某处看到异常。据了解,您不能在 WCF 中设置此标头,但您可以在自定义管道中设置它(我不明白为什么可以这样做)您可以提升一些值并使用它们来构建您的自定义值它
  • 正如 Frank Hofstaedter 指出的那样,您不能将 HTTPHeaders 上下文属性与每条消息唯一的标头一起使用。阅读 codit 博客中的最​​后一段以及 stackoverflow.com/questions/24213782/…。所以行为至少是要走的路。
猜你喜欢
  • 2020-01-18
  • 1970-01-01
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多