如何在同一个类中使用MessageContract和CollectionDataContract?

时间:2016-09-27 12:12:12

标签: c# wcf soap collections messagecontract

我有以下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”-tag):

<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?如果没有,我怎么才能接受想要的请求?

1 个答案:

答案 0 :(得分:0)

消息合约不是DataContract或CollectionDataContract! 见DataContract-Vs-MessageContract-in-WCF on codeproject

您可以说,您要声明在消费者和提供者之间传输数据的合同。此合约可以是CollectionDataContract(List)OR DataContract(class)OR MessageContract(用于详细的消息控制)