WCF:使用流式传输与消息合同

时间:2009-08-27 09:14:46

标签: c# .net wcf wcf-binding wcf-configuration

我正在尝试将WCF流与消息合同一起使用,因为我需要在流本身旁边添加其他参数。

基本上我正在创建一个文件上传和下载服务,顶部还有一些额外的逻辑。

不幸的是,当我尝试从浏览器点击服务以检查一切正常时,我收到以下错误:

'/'应用程序中的

服务器错误。 合同'IFileTransferService'中的“UploadFile”操作使用具有SOAP头的MessageContract。 None MessageVersion不支持SOAP标头。

不幸的是谷歌搜索它没有产生任何帮助我的重要结果。你们能帮助我吗?这里有服务的详细信息(由于空间原因,我删除了下载部分)。

[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(Large Data and Streaming):

  

流式传输的编程模型

     

流媒体的编程模型是   直截了当。接收   流数据,指定操作   具有单个Stream的合同   键入的输入参数。回来   流数据,返回一个Stream   参考。 [...]这个规则同样如此   适用于邮件合同。如图所示   在以下消息合同中,您   只能有一个身体成员   你的消息合同是一个   流。如果你想沟通   附加信息   流,这个信息必须是   在邮件标题中携带。该   消息正文是专门保留的   对于流内容。

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

我还看过人们完成文件上传和下载服务的博客帖子,与我试图整理的内容非常相似(例如here)。

更新2 我尝试使用basicHttpBinding创建一个小型控制台并自行托管服务,它就像魅力一样。我开始相信问题可能是IIS上的托管。有什么想法吗?

更新3 看看我自己的答案。

3 个答案:

答案 0 :(得分:8)

我终于发现了什么是错误:它与Soap版本,流等无关......我只是错误地使用FileTransfer而不是{{错误地将我自己的服务(!)的名称拼错了1}}。

最后,basicHttpBinding非常好,我不需要求助于自定义绑定。

原始(糟糕)版本:

FileTransferService

新(固定)版本:

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

我仍然不能说错误信息有助于理解这里发生了什么....

如果您对整个服务感兴趣,可以通过以下链接在我的博客上找到更多详细信息:File Transfer with WCF

答案 1 :(得分:2)

您是否需要在请求和响应中进行流式传输(即传输大量数据)?或者仅仅是响应(通常是:下载文件或大型数据集)?

如果只需要响应,则应尝试将transfermode设置为“StreamedResponse”:

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

“Streamed”设置将以两种方式进行流式传输 - 将向服务器发送请求以及来自服务器的响应将进行流式传输。通常情况下,这不是理想的情况。

马克

答案 2 :(得分:0)

使用“WCF数据服务”模板生成svc文件而不是“WCF服务”模板后,出现错误。更正服务主机文件问题已解决。