Расширение поведения WCF для BizTalk Порт отправки WCF-WebHttp не заполняется Дата Заголовок Http
У меня есть приложение BizTalk 2013 (не R2), которое должно отправлять документ Json в API RESTful внешнего поставщика. Вендору требуются три заголовка Http:
Тип контента: приложение / JSON
Дата: в формате ISO8601 UTC
Авторизация: кастомная авторизация . используя созданную строку, которая включает указанное выше значение Date, проходит через хеш HMACSHA1
В BizTalk мое исходящее (xml) сообщение отправляется на порт отправки, есть пользовательский компонент конвейера, который преобразуется в Json с помощью JSON.Net. Все идет нормально. Чтобы добавить уникальные заголовки для каждого сообщения, я создал расширение поведения WCF, которое реализует IClientInspector и IEndpointBehavior. В BeforeSendRequest() я получаю ссылку на HttpRequestMessageProperty для запроса.
Я могу успешно добавить в коллекцию заголовков заголовок ContentType и заголовок Authorization. Я не могу добавить заголовок даты - нет ошибок, просто нет значения заголовка при проверке с 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, Authorization и test date - tweDate только для тестирования, но я не могу установить фактический заголовок Date.
1 ответ
Да, действительно, Date - это специальный HTTP-заголовок, который представляет дату и время, когда сообщение было отправлено, но это не мешает вам использовать его. НО дата должна быть в формате RFC 822 вт, 15 ноября 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