51

我需要将一些以 JSON 表示的 JavaScript 对象反序列化为适当的 C# 类。鉴于自动属性的良好特性,我更愿意将它们放在这些类中,而不是仅仅拥有字段。不幸的是,.NET 序列化引擎(至少在默认情况下)完全忽略了反序列化的自动属性,只关心支持字段,这显然不存在于 JavaScript 对象中。

鉴于没有命名支持字段的标准方法,老实说,我什至不想打扰“让我们创建一个看起来像它具有 C# 支持字段的 JavaScript 对象”方法,因为这听起来有点脏,这是唯一的方法如果我可以强制序列化引擎以某种方式忽略支持字段并直接使用该属性,我可以将 JavaScript 字段序列化为 C# 自动属性。不幸的是,我无法弄清楚这是如何完成的,或者这是否可以完成。任何想法,将不胜感激。

编辑:这是一个例子:

Javascript:

function Cat()
{
    this.Name = "Whiskers";
    this.Breed = "Tabby";
}
var cat = new Cat();

然后将其序列化为“{Name: 'Whiskers'}”。

C# 类:

[Serializable()]
public class Cat
{
    public string Name { get; set; }
    public string Breed { get; set; }
}

以及失败的反序列化代码:

new DataContractJsonSerializer(typeof(Cat)).ReadObject(inputStream);

从异常中可以明显看出它失败是因为它正在寻找支持字段。

EDIT2:这是例外,如果有帮助(没有内部例外):

System.Runtime.Serialization.SerializationException

“无法反序列化数据协定类型‘Test.Cat’,因为<Name>k__BackingField, <Breed>k__BackingField找不到所需的数据成员‘’。”

4

4 回答 4

83

这里发生的是反序列化器试图猜测您的支持字段的名称。您可以通过添加显式映射(DataContract/DataMember 属性)来解决此问题,如下所示:

[DataContract]
public class Cat
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Breed { get; set; }
}
于 2009-06-03T17:38:33.827 回答
21

您可以通过JavaScriptSerializer在命名空间中找到来执行此操作System.Web.Script.Serialization

JavaScriptSerializer serializer = new JavaScriptSerializer();
Cat c = serializer.Deserialize<Cat>(jsonString);

我有具有自动属性的 POCO 对象,这很好用。

编辑:我写了关于.NET 中的 JSON 序列化器的文章,它将这个序列化器与 .NET 进行了比较DataContractJsonSerializer

于 2009-06-03T16:20:59.333 回答
5

baretta 的回答为我解决了 k__BackingField 膨胀问题。只是一个小小的附录,您可以装饰这个类以类似的方式自动序列化为 XML 或 JSON:

[Serializable, XmlRoot, DataContract]
public class Cat
{
  [XmlElement]
  [DataMember]
  public string Name { get; set; }
  [XmlElement]
  [DataMember]
  public string Breed { get; set; }
}

...然后使用 DataContractJsonSerializer 或 XmlSerializer 为您的端点准备它。

于 2010-01-29T12:56:16.337 回答
1

我假设您通过 Web 服务传递数据。如果您使用未注释掉 ScriptMethod 属性的 WebService 类,则 Web 服务方法可以原生读取 JSON。他们甚至使用上面提到的相同的 JavaScriptSerializer。如果您使用的是 WCF,我对逻辑有点模糊。

但请确保您的 JSON 对象为您的类中的每个属性返回数据。在您的错误中,提到了您的示例中没有的 Breed 属性。

此外,在 JavaScript 方面,由于 JavaScript 的动态特性,很容易向对象添加新属性。这有时会导致循环引用。您应该删除您可能添加的任何额外数据(就像您通过网络方法发送数据一样,然后在完成后再次添加)。

于 2009-06-03T16:38:01.253 回答