C# 自动属性反序列化 JSON

发布于 2024-07-22 20:40:45 字数 1276 浏览 6 评论 0原文

我需要将 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’ 无法反序列化,因为 必需的数据成员 'k__BackingField,k__BackingField' 不是 找到了。”

I need to deserialize some JavaScript object represented in JSON to an appropriate C# class. Given the nice features of automatic properties, I would prefer having them in these classes as opposed to just having fields. Unfortunately, the .NET serialization engine (at least, by default) totally ignores automatic properties on deserialization and only cares about the backing field, which is obviously not present in the JavaScript object.

Given that there's no standard way to name backing fields and to be honest I don't even want to bother with the "let's create a JavaScript object that looks like it had C# backing fields" approach as it sounds a bit dirty, the only way I could serialize JavaScript fields to C# auto-properties if I could force the serialization engine to somehow ignore the backing field and use the property directly. Unfortunately, I can't figure out how this is done or if this can be done at all. Any ideas would be appreciated.

EDIT: Here's an example:

Javascript:

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

This is then serialized to "{Name: 'Whiskers'}".

The C# class:

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

And the deserialization code, that fails:

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

And it is apparent from the exception that it fails because it is looking for the backing field.

EDIT2: Here's the exception, if that helps (no inner exceptions):

System.Runtime.Serialization.SerializationException

"The data contract type 'Test.Cat'
cannot be deserialized because the
required data members
'<Name>k__BackingField, <Breed>k__BackingField' were not
found."

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

软甜啾 2024-07-29 20:40:45

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

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

另外,在 JavaScript 方面,由于 JavaScript 的动态特性,可以轻松地向对象添加新属性。 这有时会导致循环引用。 您应该删除可能添加的所有额外数据(就像通过 Web 方法发送数据一样,完成后再次添加)。

I'm assuming you are passing data via a web service. If you are using the WebService class with the ScriptMethod attribute uncommented-out, the web service methods can read JSON natively. They even use the same JavaScriptSerializer that was mentioned above. If you are using WCF I'm a little more fuzzy on the logic.

But make sure your JSON object are returning data for EVERY property in your class. In your error, there is mention of a Breed property that is not in your example.

Also, on the JavaScript side, do to the dynamic nature of JavaScript it is easy to add new properties to your objects. This can sometimes lead to circular references. You should remove any extra data that you might have added (just as you are sending data via the web method, then add it again once you are done).

静待花开 2024-07-29 20:40:45

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

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

    [DataMember]
    public string Breed { get; set; }
}

What's happening here is the deserializer is trying to guess the name of your backing fields.
You can solve this by adding explicit mappings (DataContract/DataMember attributes) like this:

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

    [DataMember]
    public string Breed { get; set; }
}
雨落星ぅ辰 2024-07-29 20:40:45

您可以使用 System.Web.Script.Serialization 命名空间中的 JavaScriptSerializer 来执行此操作:

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

我有具有自动属性的 POCO 对象,并且效果很好。

编辑:我写了关于 .NET 中的 JSON 序列化器 ,它比较这个序列化器带有DataContractJsonSerializer

You can do this with JavaScriptSerializer found in the System.Web.Script.Serialization namespace:

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

I have POCO objects with automatic properties and this works just fine.

EDIT: I wrote about JSON Serializers in .NET which compares this serializer with DataContractJsonSerializer.

把回忆走一遍 2024-07-29 20:40:45

巴雷塔的答案为我解决了 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 为您的端点准备它。

baretta's answer solved the k__BackingField bloat for me. Just a tiny addendum that you can decorate this class to auto serialize into either XML or JSON in a similar way:

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

... and then use a DataContractJsonSerializer or XmlSerializer to prepare it for your endpoint.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文