2

我有一个 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 中定义服务的方式一定有问题,因为当我从那里删除它时,一切正常。我在这里做错了什么?

4

2 回答 2

3

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

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

<endpointBehaviors>
    <behavior name="TestBehavior">
      <webHttp />
    </behavior>
</endpointBehaviors>
于 2011-09-06T19:01:11.420 回答
1

要在 WCF 中启用流式传输,有多个限制。其中之一是有一个类型的参数Stream或其他两种类型中的任何一种。)

这可能意味着 WCF “猜测”您试图在合同中流式传输内容并默认TransferModeStreamed(这纯粹是猜测。这不是记录的内容。文档说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; }
}
于 2011-09-06T02:27:57.620 回答