2012-06-26 71 views
4

是否可以返回作爲Wcf方法返回數據的複雜對象的一部分的流?WCF - 使用流數據返回對象

我已經檢查了大多數使用Wcf查看流數據的msdn引用;如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

你不能這樣做,哪些類型的參數和返回值的this documentation

至少有一個必須是流,消息或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 

然後在您需要從流correctly閱讀,讓您的數據輸出流的另一邊。我建議先寫2 int到流中。第一個是你的infoStr字段的大小,第二個是你的文件的大小。在客戶端大小上,您先讀取這些關鍵字,然後知道需要讀取多少個字節。

+0

感謝您的詳細信息。這似乎也是我的試驗和錯誤實驗的結果。 MSDN應清楚地提到您不能將流作爲另一個對象的一部分發送出去。 – loopedcode

3

您可以使用消息的合同,設計您的合同爲

[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(); 
} 
+0

你有沒有試過這個,並且它工作? – wal

+0

一年後 - 我試過這種方法,它的工作原理 – Noah