0

Web サービス用に次のコードがあります。

[ServiceContract]
public interface IService1
{
    [OperationContract]
    WrapperResponse GetStringCollection(CustomRequest req);
}

[MessageContract(WrapperNamespace = Constants.NamespaceTem)]
public class CustomRequest
{
    [MessageBodyMember]
    public StringCollection CustomStrings
    {
        get; set;
    }
}

[CollectionDataContract(ItemName = "CustomString")]
public class StringCollection : List<string>
{
    public StringCollection(): base() { }

    public StringCollection(string[] items) : base()
    {
        foreach (string item in items)
        {
            Add(item);
        }
    }
}

このサービスは、次の SOAP リクエストを受け入れます。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">      
  <s:Body>
    <CustomRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="CustomNamespace">
      <CustomStrings xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfService1">
        <d4p1:CustomString>text1</d4p1:CustomString>
        <d4p1:CustomString>text2</d4p1:CustomString>
      </CustomStrings>
    </CustomRequest>
  </s:Body>
</s:Envelope>

ただし、次の SOAP リクエストを受け入れる必要があります (「CustomStrings」タグなし)。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">      
  <s:Body>
    <CustomRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="CustomNamespace">
      <d4p1:CustomString>text1</d4p1:CustomString>
      <d4p1:CustomString>text2</d4p1:CustomString>
    </CustomRequest>
  </s:Body>
</s:Envelope>

MessageContract を使用しない場合は、次のようになります。

[OperationContract]
WrapperResponse GetStringCollection(StringCollection CustomRequest);

私が望むものに近い、次の XML を実現できます。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <GetStringCollection xmlns="CustomNamespace">
      <CustomRequest xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <d4p1:CustomString>text1</d4p1:CustomString>
        <d4p1:CustomString>text2</d4p1:CustomString>
      </CustomRequest>
    </GetStringCollection>
  </s:Body>
</s:Envelope>

しかし、「GetStringCollection」タグが存在し、これを MessageContract が削除するのに役立ちます。

したがって、MessageContract と CollectionDataContract の両方が必要ですが、次のようにすると:

[MessageContract]
[CollectionDataContract(ItemName = "CustomString")]
public class StringCollection : List<string>
{
    public StringCollection(): base() { }

    public StringCollection(string[] items) : base()
    {
        foreach (string item in items)
        {
            Add(item);
        }
    }
}

例外があります:

「例外の詳細: System.InvalidOperationException: タイプ WcfService1.StringCollection は MessageContract を定義しますが、MessageContract を定義しないタイプ System.Collections.Generic.List`1[System.String] からも派生します。ÿ継承内のすべてのオブジェクトWcfService1.StringCollection の階層は、MessageContract を定義する必要があります。"

問題は、最上位クラスで MessageContract と CollectionDataContract の両方を使用する方法はありますか? そうでない場合、どうすれば希望のリクエストを受け入れることができますか?

4

1 に答える 1

0

メッセージ コントラクトは DataContract または CollectionDataContract ではありません。コードプロジェクトの DataContract-Vs-MessageContract-in-WCF を参照してください

コンシューマーとプロバイダーの間でデータを転送するためのコントラクトを宣言したいと言うことができます。このコントラクトは、CollectionDataContract(List) または DataContract(class) または MessageContract (詳細なメッセージ制御に使用される) のいずれかです。

于 2016-09-27T15:03:25.717 に答える