Определение app.config для службы WCF с использованием WebHttpBinding - PullRequest
1 голос
/ 06 сентября 2011

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

[OperationContract, WebInvoke(UriTemplate = "UploadFile?filename={filename}")]
bool UploadFile(string filename, Stream fileContents);

Мне разрешено использовать другой параметр, кроме объекта Stream, потому что он является частью UriTemplate.Поскольку служба работает как управляемая служба Windows, мне нужно вручную запустить ServiceHost.

protected override void OnStart(string[] args)
{
    FileServiceHost = new ServiceHost(typeof(FileService), new Uri("http://" + Environment.MachineName + ":8000/FileService"));
    FileServiceHost.AddServiceEndpoint(typeof(IFile), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
    FileServiceHost.Open();
}

При всем этом служба запускается и работает просто отлично.Однако я хотел перенести некоторые из вышеперечисленных в файл app.config.Для этого я закомментировал вторую строку OnStart и заменил первую строку на FileServiceHost = new ServiceHost(typeof(FileService)).Затем я добавил эту информацию в app.config ...

<system.serviceModel>

<services>
  <service name="Test.Server.FileService" behaviorConfiguration="DefaultBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8000/FileService"/>
      </baseAddresses>
    </host>
    <endpoint address="" binding="webHttpBinding" contract="IFile"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>
</services>

<behaviors>
  <serviceBehaviors>
    <behavior name="DefaultBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

И вдруг служба перестала запускаться.Это исключение выдается на FileServiceHost.Open метода OnStart: «Чтобы запрос в операции UploadFile был потоком, операция должна иметь один параметр, тип которого - Stream.»

Должно быть что-то не так сспособ, которым я определяю сервис в app.config, потому что, когда я удаляю его оттуда, все работает отлично.Что я здесь не так делаю?

Ответы [ 2 ]

2 голосов
/ 06 сентября 2011

Вот как я исправил проблему, добавив webHttpBinding к поведению конечной точки.

Добавил behaviorConfiguration="TestBehavior" к <endpoint address="" binding="webHttpBinding" contract="IFile"/>, а затем определил TestBehavior следующим образом:

<endpointBehaviors>
    <behavior name="TestBehavior">
      <webHttp />
    </behavior>
</endpointBehaviors>
1 голос
/ 06 сентября 2011

Для включения потоковой передачи в WCF существует несколько ограничений. Один из них должен иметь один параметр типа Stream ( или любой из двух других типов .)

Это, возможно, означает, что WCF «угадал», что вы пытались транслировать контент в своем контракте и по умолчанию от TransferMode до Streamed (Это чисто догадка . Это не то, что задокументировано. Документация гласит TransferMode по умолчанию Buffered.)

Один из вариантов - установить режим передачи на Buffered явно в XML:

<webHttpBinding>
    <binding name="MyWebBinding" transferMode="Buffered"/>
</webHttpBinding>

Однако при использовании режима передачи Buffered содержимое сообщения перед отправкой полностью буферизуется, что не очень хорошо для больших файлов.

Другой вариант - использовать режим передачи Streamed. Если вы хотите передавать содержимое файла и одновременно указывать имя файла, вам нужно определить пользовательский класс Message и отправить метаданные файла в заголовках сообщений:

[MessageContract]
public class UploadFileMessage
{
   [MessageHeader]
   public string Filename { get; set; }

   [MessageBodyMember]
   public Stream Content { get; set; }
}
...