WCF - 使用流数据返回对象

时间:2012-06-26 00:14:02

标签: c# wcf stream

是否可以从Wcf方法返回作为复杂对象一部分的流作为返回数据?

我已经使用Wcf检查了大部分msdn引用的retling流数据;例如this one。所有示例似乎都显示了当方法返回类型为Stream(或参数为流)时如何返回流。

我想知道的是,如果数据是复杂对象属性的一部分,它可以返回流吗?例如,GetData()可以返回包含流的数据,如下所示:

[DataContract]
public class Data
{
    [DataMember]
    public string Info { get; set; }

    /// <summary>
    /// This is the file stream that would be returned to client.
    /// </summary>
    [DataMember]
    public Stream File { get; set; }
}

[ServiceContract()]
public interface IService
{           
    [OperationContract]
    Data GetData();
}

从我最初的测试开始,似乎这不起作用。我在客户端遇到异常(意外的套接字关闭)。无论DataContractSerialization还是XmlSerialization,结果都是相同的。我已使用TransferMode.Streamed设置了所需的流式传输模式。

2 个答案:

答案 0 :(得分:4)

您可以使用消息合同,将合同设计为

[MessageContract]
public class Data 
{ 
    [MessageHeader(MustUnderstand = true)]
    public string Info { get; set; } 

    /// <summary> 
    /// This is the file stream that would be returned to client. 
    /// </summary> 
    [MessageBodyMember(Order = 1)]
    public Stream File { get; set; } 
} 

[ServiceContract()] 
public interface IService 
{            
    [OperationContract] 
    Data GetData(); 
} 

答案 1 :(得分:2)

您不能这样做,请参阅this documentation

  

参数和返回值的至少一种类型必须是Stream,Message或IXmlSerializable。

所以你编写它的方式不适用于TransferMode.Streamed但是该链接上的任何内容都没有明确表示类型Stream的属性不会被序列化但是根据经验我不会希望能够发挥作用。

相反,您应该返回一个Stream并将前x个字节定义为字符串Info字段。

 [ServiceContract()]
 public interface IService
 {           
     [OperationContract]
     Stream GetData();
 }

因此,当写入Stream(服务器端)时,您将执行

 stream.Write(infoStr);//check size and truncate if appropriate
 stream.Write(fileBytes);//write your file here

然后在另一方面,您需要从流correctly中读取数据,以便从流中获取数据。我建议首先将2 int写入流。第一个是infoStr字段的大小,第二个是文件的大小。在客户端大小上,首先读取这些,然后您知道需要读取多少字节。