我正在尝试将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 看看我自己的答案。
答案 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服务”模板后,出现错误。更正服务主机文件问题已解决。