是否可以将作为复杂对象一部分的流作为从 Wcf 方法返回的数据返回?
我已经检查了大多数关于使用 Wcf 重新传输流数据的 msdn 引用;例如这个。所有示例似乎都显示了当方法返回类型为 Stream(或参数为 stream)时如何返回 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();
}
从我最初的测试来看,这似乎不起作用。我在客户端遇到异常(意外的套接字关闭)。无论数据协定序列化还是 XmlSerialization,结果都是相同的。我已经使用 TransferMode.Streamed
设置了所需的流媒体模式。
您可以使用消息合约,将合约设计为
[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();
}
你不能这样做,请参阅此文档
参数和返回值的至少一种类型必须是"流"、"消息"或"IXml可序列化"。
所以你写它的方式对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
然后,另一方面,您需要正确读取流以将数据从流中取出。我的建议是先向流写入 2 int
。第一个是 infoStr 字段的大小,第二个是文件的大小。在客户端大小上,您首先读取这些内容,然后您知道需要读取多少字节。