Объект запроса WCF 413 слишком велик — WebHttpBinding с собственным размещением

Есть много дискуссий по этой проблеме, однако я испробовал все возможные решения, и мы все еще получаем от сервера ошибки 413 Request Entity Too Large.

Наша служба WCF размещается самостоятельно с помощью рабочей роли Azure и не использует IIS. Вся наша конфигурация указана в коде:

var host = new ServiceHost(searchEngine);

// Create binding
var binding = new WebHttpBinding(WebHttpSecurityMode.Transport);

binding.MaxReceivedMessageSize = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.MaxBufferPoolSize = 2147483647;

var readerQuotas = new XmlDictionaryReaderQuotas
{
    MaxStringContentLength = 2147483647,
    MaxArrayLength = 2147483647,
    MaxBytesPerRead = 2147483647,
    MaxDepth = 2147483647,
    MaxNameTableCharCount = 2147483647
};

// Setting quotas on a BindingElement after the binding is created has no effect on that binding.
// See: https://stackoverflow.com/questions/969479/modify-endpoint-readerquotas-programatically
binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, readerQuotas, null);

binding.ReceiveTimeout = new TimeSpan(1, 0, 0);
binding.SendTimeout = new TimeSpan(1, 0, 0);

// Add the service endpoint
var ep = host.AddServiceEndpoint(
    typeof(ISearchEngine),
    binding,
    string.Format("https://{0}/SearchEngine", externalEndpoint));

ep.Behaviors.Add(new WebHttpBehavior());

// Increase the MaxItemsInObjectGraph quota for all operations in this service
foreach (var operation in ep.Contract.Operations)
{
    operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = 10000000;
}

return host;

А это наша конфигурация клиента — тоже указанная в коде:

var binding = new WebHttpBinding(WebHttpSecurityMode.Transport);

binding.MaxReceivedMessageSize = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.MaxBufferPoolSize = 2147483647;

var readerQuotas = new XmlDictionaryReaderQuotas
{
    MaxStringContentLength = 2147483647,
    MaxArrayLength = 2147483647,
    MaxBytesPerRead = 2147483647,
    MaxDepth = 2147483647,
    MaxNameTableCharCount = 2147483647
};

// Setting quotas on a BindingElement after the binding is created has no effect on that binding.
// See: https://stackoverflow.com/questions/969479/modify-endpoint-readerquotas-programatically
binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, readerQuotas, null);

binding.ReceiveTimeout = new TimeSpan(1, 0, 0);
binding.SendTimeout = new TimeSpan(1, 0, 0);

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

var channelFactory = new ChannelFactory<ISearchEngine>(binding, endpointAddress);

channelFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());


// Increase the MaxItemsInObjectGraph quota for all operations in this service
foreach (var operation in channelFactory.Endpoint.Contract.Operations)
{
    operation.Behaviors.Find<DataContractSerializerOperationBehavior>().MaxItemsInObjectGraph = 10000000;
}

return channelFactory.CreateChannel();

Моя единственная догадка может быть проблемой с SSL-соединением? Есть несколько статей, в которых упоминается проблема, специфичная для IIS, однако я не уверен, что это относится к самостоятельным службам.

Любые советы очень ценятся.

ОБНОВИТЬ:

Чтобы подтвердить свою догадку, что проблема была в SSL, я временно отключил SSL, и о чудо, проблема исчезла.

Итак, теперь мне нужно выяснить, почему SSL может вызывать проблему. Существует довольно много документации по аналогичной проблеме, но она относится только к размещенным службам IIS (наша служба размещается самостоятельно из службы Windows):

IIS7 - (413) Объект запроса слишком велик | uploadReadAheadSize

Кто-нибудь знает эквивалентный параметр, который будет применяться только к службам WCF, размещенным на собственном хостинге?


person antscode    schedule 05.03.2014    source источник


Ответы (2)


Я нашел проблему благодаря этому, казалось бы, не имеющему отношения к делу сообщению:

http://forums.newatlanta.com/messages.cfm?threadid=554611A2-E03F-43DB-92F996F4B6222BC0&#top

Это была абсолютно проблема с SSL, и это связано с привязкой SSL-сертификата к порту, на котором вы размещаетесь. Вы должны привязать сертификат с помощью netsh и добавить к привязке clientcertnegotiation=enable.

В нашем случае мы уже использовали netsh, так как использовали другой порт, поэтому наша привязка теперь выглядит так:

netsh http add sslcert ipport=0.0.0.0:10100 certhash=000000089A6679262D845B650FDDE5390F0D86AB appid={000007b4-2d4b-4587-ae99-7a6627476f76} clientcertnegotiation=enable

Для тех из вас, кто размещает через IIS и изменяет значение UploadReadAheadSize, сообщение на форуме выше отмечает, что это может вызвать высокую загрузку ЦП, и вместо этого это решение может быть лучше.

person antscode    schedule 06.03.2014

В тех случаях, когда вам необходимо передать большие данные, следует использовать transferMode="Streaming".

Взгляните на эту статью от MS:

http://msdn.microsoft.com/en-us/library/ms733742(v=vs.110).aspx

person Thiago Custodio    schedule 05.03.2014
comment
Спасибо. Я также пробовал это, но затем обнаружил, что режим потоковой передачи не работает с базовой аутентификацией, которую мы используем. Тем не менее, наши данные крошечные: 100-200 КБ, поэтому я думаю, что проблема здесь не в отсутствии потоковой передачи. - person antscode; 06.03.2014