Наконец-то решили эту неприятную проблему. На самом деле было две проблемы.
Проблема № 1: Служба данных WCF, размещенная в IIS за балансировщиком нагрузки с https, создает каналы с http URI, а не https. Это понятно и было моей первой догадкой. Через много копаний я наткнулся на эту статью, в которой было довольно простое решение.
В конструкторе моего сервиса я подключаюсь к событию запроса на обработку
ProcessingPipeline.ProcessingRequest += ProcessingPipeline_ProcessingRequest;
В обработчике событий я использовал упомянутую статью и сделал несколько настроек, которые в основном берут хост, схему и порт из clientExpectedUri и применяют их к Uri запроса. Я также просто ищу специальный заголовок, который я назвал «X-Client-Expected-RootUri», который необходимо отправлять клиентам за пределами брандмауэра, если они хотят действительные каналы.
static void ProcessingPipeline_ProcessingRequest(object sender, DataServiceProcessingPipelineEventArgs e)
{
if (e.OperationContext.RequestHeaders.AllKeys.Contains(ClientExpectsUriKey))
ProcessUri(new Uri(e.OperationContext.RequestHeaders[ClientExpectsUriKey]));
}
private static void ProcessUri(Uri clientExpectsRootUri)
{
if (clientExpectsRootUri != null)
{
var requestUri = OperationContext.Current.IncomingMessageProperties.ContainsKey("MicrosoftDataServicesRequestUri")
? OperationContext.Current.IncomingMessageProperties["MicrosoftDataServicesRequestUri"] as Uri : HttpContext.Current.Request.Url;
var serviceUri = clientExpectsRootUri;
var serviceUriBuilder = new UriBuilder(serviceUri);
var requestUriBuilder = new UriBuilder(requestUri)
{
Host = serviceUriBuilder.Host,
Scheme = serviceUriBuilder.Scheme,
Port = serviceUriBuilder.Port
};
if (!serviceUriBuilder.Path.EndsWith("/")) //the base uri should end with a slash...
serviceUriBuilder.Path = serviceUriBuilder.Path += "/";
OperationContext.Current.IncomingMessageProperties["MicrosoftDataServicesRootUri"] = serviceUriBuilder.Uri;
OperationContext.Current.IncomingMessageProperties["MicrosoftDataServicesRequestUri"] = requestUriBuilder.Uri;
}
}
Мне бы хотелось получить отзывы об этом проекте, так как я в основном прошу клиента рассказать мне, как вернуть URI через пользовательский заголовок. В будущем я попытаюсь изменить балансировщик нагрузки для автоматического добавления этих заголовков.
Проблема № 2. Балансировщик нагрузки не настроен для MERGE и других не RFC-методов http. Решение этой проблемы было простым, просто установите usePostTunneling в true для DataServiceContext. Если у кого-то есть скрипты для включения не RFC-методов http для cisco 11503, я бы хотел их иметь. ; -)