3

この投稿の長さについて申し訳ありませんが始める前に...

クラスの配列を動的プロパティとしてWCFに渡せない理由を誰かが知っていますか?

以下に示すように、ソリューションの周りにメッセージを渡すために使用されるServiceOperationResponseクラスがあります。

メッセージ詳細データメンバーは動的タイプであり、任意のオブジェクトを簡単に渡すことができます。これは、WCFサーバーインターフェイスごとにServiceKnownTypeを設定できるため、ほぼすべての状況で正常に機能します。

ただし、MessageDetailsプロパティ自体がServiceOperationResponseタイプの配列またはリストであるときに、ServiceOperationResponseオブジェクトをWCFを介して渡そうとすると、次のエラーが発生します。

InnerExceptionメッセージは「1行目の576のエラー」でした。要素「http://schemas.datacontract.org/2004/07/Library:MessageDetails」には、「http://schemas.datacontract」という名前にマップされるタイプのデータが含まれています。 .org / 2004/07 / Library:ArrayOfServiceOperationResponse'。デシリアライザーは、この名前にマップされるタイプを認識していません。

これは、ServiceKnownTypeをServiceOperationResponse []、Listのいずれかに設定した場合に発生します。

他のタイプのリストまたは配列は問題なく渡すことができます。また、ServiceOperationResponse []タイプの別のプロパティ、つまり応答の配列をメインのServiceOperationResponseに作成し、代わりにこれを設定すると、すべてのデータが適切に逆シリアル化されます。ただし、可能であれば、特定の1つの場合にのみこのプロパティを追加する必要がないことをお勧めします。

/// <summary>
/// Class used to pass details between services
/// </summary>
[DataContract]
public class ServiceOperationResponse
{
    /// <summary>
    /// the originating hostname or keyname
    /// </summary>
    [DataMember]
    public string HostName { get; set; }

    /// <summary>
    /// the operation name
    /// </summary>        
    public string OperationName { get; set; }

    /// <summary>
    /// the particular message details
    /// </summary>
    [DataMember]
    public dynamic MessageDetails { get; set; }
}

以下に示すのは、WCFからクライアントにパスバックしようとすると失敗をトリガーするサンプルコードです。

var responseList = new List<ServiceOperationResponse>();
        for (int i = 0; i < 3; i++)
        {
            var responseElement = new ServiceOperationResponse()
            {
                HostName = Environment.MachineName,
                MessageDetails = "this is a test"
            };
          responseList.Add(responseElement);
        }

        var response = new ServiceOperationResponse()
        {
            HostName = Environment.MachineName,
            OperationName = "Get a list of service responses",
            MessageDetails = responseList
        };
4

1 に答える 1

1

WCFは、通信に契約の概念を使用します。コントラクトは、特に、送信されるデータの形状を指定します。つまり、運用契約は明確に定義された形でなければなりません。動的(またはメタデータで表されるオブジェクト)には、明確に定義された形状がありません。

これを回避するには、KnownTypeAttributeをDataContractクラスに追加し、送信される可能性があるがコントラクトクラスの定義に明示的に含まれていないデータのタイプを指定します。ただし、これは、動的プロパティに存在する可能性のあるすべてのオブジェクトのすべての可能なタイプを事前に知っている場合にのみ機能します。

まず、DataContractに動的プロパティがある理由を質問することから始めます。

于 2012-04-04T17:58:38.017 に答える