使用 WebHttpBinding 为 WCF 服务定义'app.config'



我有一个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>

突然服务不能再启动。它在OnStart方法的FileServiceHost.Open上抛出了这个异常:"对于操作UploadFile中的请求是一个流,该操作必须有一个类型为流的参数。"

我在app.config中定义服务的方式一定有问题,因为当我从那里删除它时,一切都很好。我哪里做错了?

我是如何通过将webHttpBinding添加到端点行为来解决这个问题的

behaviorConfiguration="TestBehavior"添加到<endpoint address="" binding="webHttpBinding" contract="IFile"/>,然后定义TestBehavior如下:

<endpointBehaviors>
    <behavior name="TestBehavior">
      <webHttp />
    </behavior>
</endpointBehaviors>

要在WCF中启用流,有多个限制。其中之一是只有一个类型为Stream的形参(或其他两种类型中的任何一种)

这可能意味着WCF"猜测"您正在尝试流式传输合同中的内容并将TransferMode默认为Streamed(这纯粹是一个猜测。这不是文献记载的。文档显示TransferMode默认为Buffered)

一个选项是在XML中显式地将传输模式设置为Buffered:

<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; }
}

相关内容

  • 没有找到相关文章

最新更新