WCF: использование потоковой передачи с контрактами сообщений

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

В основном я создаю службу загрузки и загрузки файлов с некоторой дополнительной логикой сверху.

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

ошибка сервера в приложении"/". Операция "UploadFile" в контракте "IFileTransferService" использует MessageContract, который имеет заголовки SOAP. Заголовки SOAP не поддерживаются параметром None MessageVersion.

к сожалению, googling для него не дал никакого значительного результата, который помог мне. Ребята, вы можете мне помочь? Вот детали сервиса (я удалил часть загрузки по причине пространства).

[ServiceContract(Namespace = "http://www.acme.org/2009/04")]
public interface IFileTransferService
{
    [OperationContract(Action = "UploadFile")]
    void UploadFile(FileUploadMessage request);
}

[MessageContract]
public class FileUploadMessage
{
    [MessageHeader(MustUnderstand = true)]
    public FileMetaData Metadata { get; set; }

    [MessageBodyMember(Order = 1)]
    public Stream FileByteStream { get; set; }
}

[DataContract(Namespace = "http://schemas.acme.org/2009/04")]
public class FileMetaData
{
    [DataMember(Name="FileType", Order=0, IsRequired=true)]
    public FileTypeEnum fileType;

    [DataMember(Name="localFilename", Order=1, IsRequired=false)]
    public string localFileName;

    [DataMember(Name = "remoteFilename", Order = 2, IsRequired = false)]
    public string remoteFileName;
}

Я попытался использовать как basichttpbinding, так и привязку customhttp с не положительным эффект:

<customBinding>
    <binding name="customHttpBindingStream">
        <textMessageEncoding messageVersion="Soap12" />
        <httpTransport transferMode="Streamed" maxReceivedMessageSize="2147483647"/>
    </binding>
</customBinding>

обновление чтение документации кажется, что течь с MessageContracts должно быть возможно. См., например, MSDN ( большие данные и потоковое):

модель программирования для потоковой передачи

модель программирования для потоковой передачи простой. Для получения потоковые данные, укажите операцию контракт, который имеет один поток типизированный входной параметр. Для возвращения потоковые данные, возврат потока ссылка. [...] Это правило аналогично применяется к контрактам сообщений. Как показано в следующем контракте сообщения Вы может иметь только один элемент тела в ваш контракт на сообщение, который является поток. Если вы хотите общаться дополнительная информация с поток, эта информация должна быть переносится в заголовках сообщений. Этот тело сообщения зарезервировано для потока содержание.

[MessageContract]
public class UploadStreamMessage
{
   [MessageHeader]
   public string appRef;
   [MessageBodyMember]
   public Stream data;
} 

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

обновление 2 Я попытался создать небольшую консоль и самостоятельно разместить сервис с basicHttpBinding, и там он работает как шарм. Я начинаю верить, что проблема может быть хостинг на IIS. Любой идея?

обновление 3 См. мой собственный ответ.

3 ответов


Я, наконец, узнал, что было ошибкой: это не имело ничего общего с версиями Soap, потоками и т. д... Я просто mispelled имя мое служение (!), используя FileTransfer вместо FileTransferService.

в конце basicHttpBinding было прекрасно, мне не нужно было прибегать к пользовательской привязке.

оригинальный (БАД) версия:

<service 
    behaviorConfiguration="serviceBehavior"
    name="Acme.Service.FileTransfer">
    <endpoint address="" 
        name="basicHttpStream" 
        binding="basicHttpBinding"
        bindingConfiguration="httpLargeMessageStream" 
        contract="Acme.Service.IFileTransferService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>

новая (исправленная) версия:

<service 
    behaviorConfiguration="serviceBehavior"
    name="Acme.Service.FileTransferService">
    <endpoint address="" 
        name="basicHttpStream" 
        binding="basicHttpBinding"
        bindingConfiguration="httpLargeMessageStream" 
        contract="Acme.Service.IFileTransferService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>

все же я не могу сказать, что сообщение об ошибке было полезно каким-либо образом понять что здесь происходит?...

если вас интересует весь сервис, вы можете найти более подробную информацию о моем блоге по следующей ссылке: передача файлов с помощью WCF


вам нужна потоковой передачи (т. е. передачи humonguous объемы данных) на запрос и ответ? Или просто на ответ (как правило: загрузка файла или большого набора данных)?

Если вам нужен только ответ, вы должны попытаться установить transfermode в "StreamedResponse":

<customBinding>
    <binding name="customHttpBindingStream">
        <textMessageEncoding messageVersion="Soap12" />
        <httpTransport transferMode="StreamedResponse" 
                       maxReceivedMessageSize="2147483647"/>
    </binding>
</customBinding>

параметр "Streamed" будет транслироваться в обе стороны - как запрос, идущий на сервер, так и ответ с сервера, будут транслироваться. Чаще всего, это не идеальный сценарий.

Марк


Я получил ошибку после использования шаблона "служба данных WCF" для создания svc-файла вместо шаблона "служба WCF". Исправление файла service host проблема была решена.