【问题标题】:how to pass List<Object> to WCF如何将 List<Object> 传递给 WCF
【发布时间】:2010-07-20 10:07:03
【问题描述】:

我已经配置了我的服务参考并将我的集合设置为 Generic.List 。

当我用字符串或整数填充List&lt;Objects&gt; 时,它工作正常。但是当我用List&lt;String&gt; 填充它时,它会给出一个运行时错误while trying to serialize parameter

那么有没有办法将包含多个List&lt;String&gt;List&lt;Objects&gt; 传递给WCF?

【问题讨论】:

  • 如果您发布代码或 XML(如您的 List&lt;Object&gt;,请在文本编辑器中突出显示文本(或行),然后单击编辑器工具栏上的“代码”按钮 (101 010) (或按 Ctrl-K) 以很好地格式化和语法突出显示它!

标签: c#


【解决方案1】:

在您的数据合同中使用KnownType 属性。见Data Contract Known Types

[KnownType(typeof(List<string>))]
[DataContract]
public class YourClass
{
    [DataMember]
    public List<object> YourList { get; set; }
}

【讨论】:

  • 我认为MSDN 会针对这种用法发出警告:“这仅在使用 SVCUTIL.EXE 生成 WCF 代理时才适用于客户端。SVCUTIL.EXE 从服务中检索元数据包括任何已知类型。如果没有这些信息,客户端将无法反序列化这些类型。"
【解决方案2】:

使用 XmlSerializer 类:

Windows Communication Foundation (WCF) 可以使用两种不同的序列化技术将应用程序中的数据转换为在客户端和服务之间传输的 XML,这一过程称为序列化。

DataContractSerializer 作为默认值:

默认情况下,WCF 使用 DataContractSerializer 类来序列化数据类型。此序列化程序支持以下类型: 基元类型(例如,整数、字符串和字节数组),以及一些特殊类型,例如 XmlElement 和 DateTime,它们都被视为基元。

数据协定类型(用 DataContractAttribute 属性标记的类型)。

标有 SerializableAttribute 属性的类型,包括实现 ISerializable 接口的类型。

实现 IXmlSerializable 接口的类型。

许多常见的集合类型,其中包括许多通用集合类型。

许多 .NET Framework 类型属于后两类,因此是可序列化的。可序列化类型的数组也是可序列化的。有关完整列表,请参阅在服务合同中指定数据传输。 与数据协定类型一起使用的 DataContractSerializer 是编写新 WCF 服务的推荐方法。有关详细信息,请参阅使用数据协定。

何时使用 XmlSerializer 类:

WCF 还支持 XmlSerializer 类。 XmlSerializer 类不是 WCF 独有的。它与 ASP.NET Web 服务使用的序列化引擎相同。 XmlSerializer 类支持比 DataContractSerializer 类更窄的类型集,但允许对生成的 XML 进行更多控制,并支持更多的 XML 架构定义语言 (XSD) 标准。它也不需要可序列化类型的任何声明性属性。有关详细信息,请参阅 .NET Framework 文档中的 XML 序列化主题。 XmlSerializer 类不支持数据协定类型。 在使用 Svcutil.exe 或 Visual Studio 中的添加服务引用功能为第三方服务生成客户端代码或访问第三方架构时,会自动为您选择适当的序列化程序。如果架构与 DataContractSerializer 不兼容,则选择 XmlSerializer。

手动切换到 XmlSerializer:

有时,您可能必须手动切换到 XmlSerializer。例如,在以下情况下会发生这种情况: 将应用程序从 ASP.NET Web 服务迁移到 WCF 时,您可能希望重用现有的与 XmlSerializer 兼容的类型,而不是创建新的数据协定类型。

当精确控制出现在消息中的 XML 很重要,但 Web 服务描述语言 (WSDL) 文档不可用时,例如,当创建具有必须符合某个标准化、已发布架构的类型的服务时与 DataContractSerializer 不兼容。

创建遵循旧版 SOAP 编码标准的服务时。

在这些和其他情况下,您可以通过将 XmlSerializerFormatAttribute 属性应用于您的服务来手动切换到 XmlSerializer 类,如以下代码所示。

[ServiceContract]
[XmlSerializerFormat]
public class BankingService
{
[OperationContract]
    public void ProcessTransaction(BankingTransaction bt)
    {
        // Code not shown.
    }

}

//BankingTransaction is not a data contract class,
//but is an XmlSerializer-compatible class instead.
public class BankingTransaction
{
    [XmlAttribute]
    public string Operation;
    [XmlElement]
    public Account fromAccount;
    [XmlElement]
    public Account toAccount;
    [XmlElement]
    public int amount;
}
//Notice that the Account class must also be XmlSerializer-compatible.

【讨论】:

    【解决方案3】:

    我认为您需要传递一个对象数组,而不是尝试使用泛型。 Web 服务与平台无关,因此可能需要被任何客户端使用 - 如果 .NET 1.x 应用程序试图访问该服务怎么办?

    【讨论】:

      【解决方案4】:

      我在 WCF 服务中传递通用列表时遇到了同样的问题。 这样做的原因是默认情况下DataContractSerializer 用于序列化数据。 使用XmlSerializer 为我解决了这个问题。

      更多信息:http://msdn.microsoft.com/en-us/library/ms733901.aspx

      【讨论】:

        【解决方案5】:

        您是否尝试将列表作为“字符串列表列表”而不是“对象列表”传递?当您将列表作为对象传递时,SOAP 可能缺少序列化信息......

        List<List<String>> allYourStringLists = new List<List<String>>();
        List<String> firstStringList = new List<String> { "a", "b" };
        
        allYourStringLists.add(firstStringList);
        

        然后传递“allYourStringLists”对象

        【讨论】:

          【解决方案6】:

          嗯... 所以你想传递一个字符串列表。对吗?

          那为什么不这样做呢?

          List<List<string>>
          

          【讨论】:

          • 因为我不仅在传递 List。有时它的 string,int ..... 但只有在添加 List 时才会出现错误
          • 嗯...好吧。您是否尝试将内部列表作为数组传递?
          猜你喜欢
          • 2014-06-08
          • 2015-07-26
          • 2015-05-10
          • 1970-01-01
          • 2017-10-28
          • 1970-01-01
          • 2014-10-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多