4

複雑なオブジェクトの一部であるストリームを、Wcfメソッドから返されたデータとして返すことは可能ですか?

Wcfを使用してストリームデータを取得する際のmsdn参照のほとんどを確認しました。このような。すべての例は、メソッドの戻りタイプが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();
}

私の最初のテストから、これは機能しないようです。クライアント側で例外が発生します(予期しないソケットの閉鎖)。結果は、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

それはできません。このドキュメントを参照してください

パラメーターと戻り値の型の少なくとも 1 つは、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 を書き込むことです。1 つ目は infoStr フィールドのサイズで、2 つ目はファイルのサイズです。クライアントのサイズでは、最初にこれらを読み取ってから、読み取る必要があるバイト数がわかります。

于 2012-06-26T00:39:46.157 に答える