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

时间:2011-09-06 01:57:25

标签: c# wcf webhttpbinding

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

答案 0 :(得分:2)

以下是我通过将webHttpBinding添加到端点行为来解决问题的方法。

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

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

答案 1 :(得分:1)

要在WCF中启用流式传输,有多种限制。其中之一是拥有Streamor any of two other types类型的单个参数。)

这可能意味着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; }
}