none
Передача большого массива байт на сервер. RRS feed

  • Вопрос

  • C#, VS2012, .NET FW 4-4,5

    Форумчане! Помогите пожалуйста с конфигом сервера.

    Есть служба доступа к данным WCF.

    Есть вот такой объект который я хочу принять от клиента:

    [DataContract]
    public class FileData
    {
        [DataMember]
        public byte[] Buffer;
        [DataMember]
        public string FileName;
        [DataMember]
        public string FileVersion;
    }

    Вот как выглядит метод который его принимает:

    [OperationContract]
    public bool UploadFile(string Login, string Password, FileData FData)
    {
        return true; //Это я умышленно заоконечил для того что бы исключить ошибки самого метода и сосредоточится на отладке именно передачи.
    
        string Query = GetQuery(Commands.UploadFile);
        object Result = null;
    
        SqlConnection sqlConnection = new SqlConnection(connectionString);
        using (sqlConnection)
        {
            SqlCommand sqlCommand = new SqlCommand(Query, sqlConnection);
    
            sqlCommand.Parameters.AddWithValue("@Version", FData.FileVersion);
            sqlCommand.Parameters.AddWithValue("@File", FData.Buffer);
            sqlCommand.Parameters.AddWithValue("@Date", DateTime.Now);
    
            sqlConnection.Open();
    
            try { Result = sqlCommand.ExecuteNonQuery(); }
            catch { }
        }
    
        if (Result != null)
        {
            if ((int)Result == 1)
                return true;
        }
        return false;
    }

    Пока размер массива Buffer < 16K все нормально, но когда я его превышаю получаю вот такое исключение:

    Необработанное исключение типа "System.ServiceModel.ProtocolException" в mscorlib.dll

    Дополнительные сведения: Форматтер сгенерировал исключение при попытке десериализовать сообщение: Ошибка десериализации параметра http://tempuri.org/:FData. Сообщение InnerException было "Ошибка десериализации объекта типа ClipServise.ClipWorks+FileData. Превышена квота максимальной длины массива (16384) при чтении данных XML. Эту квоту можно увеличить, изменив свойство MaxArrayLength объекта.

    Курил google, наш форум, и пришел к выводу что мне необходимо настроить конфиг сервера.

    Вот что я наваял на данный момент.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <bindings>
          <customBinding>
            <binding name="ClipBinding">
              <binaryMessageEncoding>
                <readerQuotas maxArrayLength="1048576" />
              </binaryMessageEncoding>
              <httpTransport transferMode="Buffered" maxBufferSize="2097152" maxReceivedMessageSize="2097152" />
            </binding>
          </customBinding>
        </bindings>
    
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    
        <services>
          <service name="ClipWorks">
            <endpoint address="" binding="customBinding" bindingConfiguration="ClipBinding"
              contract="UploadFile" />
            <endpoint address="" binding="customBinding" bindingConfiguration="ClipBinding"
              contract="FileData" />
          </service>
        </services>
        
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <directoryBrowse enabled="true"/>
      </system.webServer>
    
    </configuration>

    Но сообщение об ошибке прежнее. Подскажите что я не так делаю?

    • Изменено JusteG 11 марта 2013 г. 8:22
    11 марта 2013 г. 8:20

Ответы

Все ответы

  • А того размера (2097152), который вы сделали, хватает для файла? Может еще увеличить?

    Вообще в таких вариантах, мне кажется, лучше использовать Stream.

    11 марта 2013 г. 9:45
  • Да, хватает. Размер файла много меньше миллиона. Где то 250К да и к тому же в ошибке говорится про 16К. Такое ошущение что настройки не притягиваются...
    11 марта 2013 г. 10:19
  • Надо прописывать MaxArrayLength и на сервере и на клиенте... Попробуйте, должно помочь...
    12 марта 2013 г. 6:48
  • Один из примеров использования высокоуровневых конструкций, устройство которых тебе не известно. Имхо нужно использовать асинхронную передачу частями. Возможно даже через этот же самый сервис, просто посылай данные по частям и дописывай их в конец файла.
    • Предложено в качестве ответа Abolmasov Dmitry 25 марта 2013 г. 8:51
    12 марта 2013 г. 19:56
  • Как вариант решения проблемы, спасибо. Но хотелось бы все таки решить  задачу "правильно"...
    • Изменено JusteG 13 марта 2013 г. 8:03
    13 марта 2013 г. 8:02
  • Прописал на клиенте вот так:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <bindings>
                <customBinding>
                    <binding name="ClipBinding">
                        <binaryMessageEncoding>
                            <readerQuotas maxArrayLength="1048576" />
                        </binaryMessageEncoding>
                        <httpTransport maxReceivedMessageSize="2097152" maxBufferSize="2097152"
                            transferMode="Buffered" />
                    </binding>
                </customBinding>
            </bindings>
          
            <client>
                <endpoint address="[Мой адрес службы]" binding="customBinding"
                    bindingConfiguration="ClipBinding" contract="ServiceReference1.ClipWorks"/>
                <endpoint address="[Мой адрес службы]" binding="customBinding"
                    bindingConfiguration="ClipBinding" contract="ServiceReference1.ClipWorksFileData"/>
            </client>
        </system.serviceModel>
    </configuration>

    Теперь другая ошибка:

    Тип содержимого application/soap+msbin1 не поддерживается службой [Мой адрес службы]. Это может быть вызвано несоответствием привязок клиента и службы.

    13 марта 2013 г. 8:06
  • Вопрос всё еще актуален.

    Иногда мне кажется что MS "перестарались".

    15 марта 2013 г. 8:00
  • Попробуйте вместе с maxArrayLength прописать и другие праметры для readerQuotas:
    <readerQuotas maxDepth="2147483647"
    maxStringContentLength="2147483647"
    maxArrayLength="2147483647"
    maxBytesPerRead="2147483647"
    maxNameTableCharCount="2147483647" />
    По второму вопросу, возможно поможет похожая тема WCF - Binary Encoding over HTTP throwing client and service binding mismatch exception

    Для связи [mail]

    18 марта 2013 г. 8:06
  • И снова:

    Тип содержимого application/soap+msbin1 не поддерживается службой [Мой адрес службы]. Это может быть вызвано несоответствием привязок клиента и службы.

    Чтож такое то?
    • Изменено JusteG 18 марта 2013 г. 11:48
    18 марта 2013 г. 11:43
  • И снова:

    Тип содержимого application/soap+msbin1 не поддерживается службой [Мой адрес службы]. Это может быть вызвано несоответствием привязок клиента и службы.

    Чтож такое то?

    Мне кажется проблема в том, что контракты не совпадают у клиента и сервера, поэтому не использует правильные бинды и выдает ошибку.
    19 марта 2013 г. 8:05
    Модератор
  • Когда то лет 8 назад, мы использовали веб сервисы в крупном проекте, с тех пор я поклялся не использовать больше веб сервисы или другие высокоуровневые классы, решения, технологии.
    19 марта 2013 г. 9:57
  • Может какая нибудь хитрая галочка в IISе не стоит?
    20 марта 2013 г. 23:41
  • Может какая нибудь хитрая галочка в IISе не стоит?

    Не знаю, подобного варианта решения ошибки не видел.

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

    WCF - Binary Encoding over HTTP throwing client and service binding mismatch exception

    WCF: Enable Binary Encoding Over Http

    21 марта 2013 г. 8:34
    Модератор