4

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

我已经检查了大多数关于使用 Wcf 恢复流数据的 msdn 参考资料;比如这个。当方法返回类型为流(或参数为流)时,所有示例似乎都显示了如何返回流。

我想知道的是,如果数据是复杂对象属性的一部分,它可以返回流吗?例如,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

4

2 回答 2

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(); 
} 
于 2012-06-26T04:39:25.320 回答
2

您不能这样做,请参阅此文档

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

因此,您编写它的方式行不通,TransferMode.Streamed但是该链接上没有任何内容明确表示Stream不会序列化类型的属性,但根据经验,我不希望它起作用。

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

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

因此,当写入流(服务器端)时,你会做

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

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

于 2012-06-26T00:39:46.157 回答