【问题标题】:How to use both MessageContract and CollectionDataContract in the same class?如何在同一个类中同时使用 MessageContract 和 CollectionDataContract?
【发布时间】:2016-09-27 12:12:12
【问题描述】:

我有以下 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?如果没有,我该如何接受通缉请求?

【问题讨论】:

    标签: c# wcf soap collections messagecontract


    【解决方案1】:

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

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

    【讨论】:

    • 那么我怎样才能达到想要的要求呢?
    • @Godspark,您只需要使用 CollectionDataContract 并在您的 OperationContract 中使用它。只需删除 [MessageContract] 属性即可。
    • 但是我最终得到了问题的第三个请求,其中包含额外的“”标签对。在不使用 MessageContract 的情况下如何避免这种情况?
    猜你喜欢
    • 2019-08-24
    • 2021-09-23
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 2016-01-03
    • 2016-06-01
    • 2014-09-19
    • 1970-01-01
    相关资源
    最近更新 更多