Исключение протокола WCF: неверный запрос 400 (связанный с размером http-сообщения)

#c# #wcf #base64 #channel #webhttpbinding

#c# #wcf #base64 #канал #webhttpbinding

Вопрос:

Я пытаюсь передать строку в кодировке base64 через WCF, используя webHttpBinding.

Я получаю загадочную ошибку «Неверный запрос 400», что сервер не отвечает. Я знаю, что это связано с размером строки, потому что, если я тестирую очень короткую строку (около 4 КБ или около того), она работает, но все, что даже немного больше, — нет.

Я везде читал, что это связано с maxReceivedMessageSize или другой конфигурацией в web.config для привязки, но даже после изменения этих цифр как на клиенте, так И на сервере я все еще получаю ошибку (другими словами, я прочитал много других сообщений об этой точной проблеме, но они, похоже, не помогли?)

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

 static IHttpDataPush push = new HttpDataPush();

var wcfClient = ChannelHelperExtensions.WebHttpChannel<IHttpDataRcv>("http://localhost:3941/HttpRcv");

        var args = wcfClient.OptionArgs();

        foreach (var v in args)
        {
            HttpTransactionDataArgs uid = push.Option(v.Entity, v.Option, v.Key);

            wcfClient.ResponseNotification(uid); <-- error thrown at this line
  

Это мои контракты на обслуживание / контракты на передачу данных:

 [ServiceContract]
public interface IHttpDataPush
{
    [OperationContract]
    HttpTransactionDataArgs DbRequest(HttpTransactionOptionArgs args);

    [OperationContract]
    [WebGet]
    HttpTransactionDataArgs DbOption(string entity, string option, string key);
}

[DataContract]
[KnownType(typeof(HttpTransactionDataArgs))]
public class HttpTransactionDataArgs
{
    [DataMember]
    public string EntityName { get; set; }

    [DataMember]
    public string Base64Schema { get; set; }

    [DataMember]
    public string Base64Data { get; set; }

    [DataMember]
    public bool TransactionSuccessful { get; set; }
}
  

Контракты для принимающей стороны отправки данных:

 [ServiceContract]
public interface IHttpDataRcv
{
    [OperationContract]
    HttpTransactionOptionArgs[] OptionArgs();

    [OperationContract]
    bool ResponseNotification(HttpTransactionDataArgs args);
}

[DataContract]
[KnownType(typeof(HttpTransactionOptionArgs))]
public class HttpTransactionOptionArgs
{
    [DataMember]
    public string Entity { get; set; }

    [DataMember]
    public string Option { get; set; }

    [DataMember]
    public string Key { get; set; }
}
  

Серверный web.config:

 <bindings>
  <webHttpBinding>
    <binding name="webHttpConfig" closeTimeout="00:20:00" openTimeout="00:20:00"
        receiveTimeout="00:20:00" sendTimeout="00:20:00"
        maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" >
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
          maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
    </binding>

<endpoint address="/HttpRcv" behaviorConfiguration="REST" bindingConfiguration="webHttpConfig" binding="webHttpBinding" contract="EmailContracts.IHttpDataRvc" />
  

Веб-конфигурация на стороне клиента (где выдается ошибка 🙂

 <client>
  <endpoint address="http://localhost:3941/HttpRcv"
            binding="webHttpBinding"
            bindingConfiguration="webHttpConfig"
            contract="EmailContracts.IHttpDataRcv" />
</client>

    <bindings>
  <webHttpBinding>
    <binding name="webHttpConfig" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
      <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" 
                    maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
    </binding>      
  </webHttpBinding>
</bindings>
  

Комментарии:

1. Я не знаю, но если вы настроите трассировку для веб-службы, это может предоставить некоторую полезную информацию о том, почему была сгенерирована ошибка.

2. У меня есть трассировка. Не видел никаких явных всплывающих ошибок, но я пока не слишком разбираюсь в том, как перемещаться по журналу трассировки. Я рассмотрю это подробнее.

Ответ №1:

Вы размещаете в IIS / ASP.NET? Если это так, вы также должны увеличить их настройки.

Для IIS7 вы хотите изменить system.webServer/security/requestFiltering/requestLimits/@maxAllowedContentLength .

Для ASP.NET вы хотите изменить system.web/httpRuntime/@maxRequestLength .

Комментарии:

1. Это все в Visual Studio, с использованием локального сервера разработки.

2. Вы пробовали их устанавливать? Параметр HttpRuntime также повлияет на сервер разработки Cassini. Тем не менее, в какой-то момент вы развернете это в IIS, верно? Таким образом, вы тоже должны включить system.webServer туда.

3. Я увеличил HttpRuntime maxRequestLength, но все равно получаю ту же ошибку.

4. Хорошо, вы включили трассировку WCF, чтобы увидеть, достигается ли WCF вообще? Если это не так, вы знаете, что это уровень HTTP, который отклоняет запрос. Можете ли вы изменить использование IIS или IISExpress для тестирования?

5. Мой журнал трассировки работает и определенно показывает большинство ошибок, однако эта ошибка не приводит к появлению ошибки в журнале трассировки на стороне сервера (возможно, что-то происходит на стороне клиента?). Единственное, что я вижу на трассировках на стороне сервера, — это связка ‘Construct ServiceHost’ и ‘ASP.net сообщения, активированные размещенной службой». Ошибка в журнале трассировки на стороне сервера отсутствует. Также это немного необычная ситуация, поскольку клиент фактически пытается отправить большой набор данных на сервер, если вы заметили. Возможно, это нужно учитывать? Это не обычный клиент, извлекающий данные с сервера.