JavaScriptSerializer.Deserialize - 如何更改字段名称 [英] JavaScriptSerializer.Deserialize - how to change field names

查看:36
本文介绍了JavaScriptSerializer.Deserialize - 如何更改字段名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结:如何在使用 JavaScriptSerializer.Deserialize 时将 JSON 数据中的字段名称映射到 .Net 对象的字段名称?

Summary: How do I map a field name in JSON data to a field name of a .Net object when using JavaScriptSerializer.Deserialize ?

更长的版本:我有以下来自服务器 API 的 JSON 数据(未在 .Net 中编码)

Longer version: I have the following JSON data coming to me from a server API (Not coded in .Net)

{"user_id":1234, "detail_level":"low"}

我有以下 C# 对象:

I have the following C# object for it:

[Serializable]
public class DataObject
{
    [XmlElement("user_id")]
    public int UserId { get; set; }

    [XmlElement("detail_level")]
    public DetailLevel DetailLevel { get; set; }
}

其中 DetailLevel 是一个枚举,其中低"作为值之一.

Where DetailLevel is an enum with "Low" as one of the values.

此测试失败:

[TestMethod]
public void DataObjectSimpleParseTest()
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    DataObject dataObject = serializer.Deserialize<DataObject>(JsonData);

    Assert.IsNotNull(dataObject);
    Assert.AreEqual(DetailLevel.Low, dataObject.DetailLevel);
    Assert.AreEqual(1234, dataObject.UserId);
}

最后两个断言失败,因为这些字段中没有数据.如果我将 JSON 数据更改为

And the last two asserts fail, since there is no data in those fields. If I change the JSON data to

 {"userid":1234, "detaillevel":"low"}

然后就过去了.但是我无法更改服务器的行为,并且我希望客户端类在 C# 习惯用法中具有命名良好的属性.我不能使用 LINQ to JSON,因为我希望它在 Silverlight 之外工作.看起来 XmlElement 标签没有效果.我不知道我从哪里得到的想法它们完全相关,它们可能不相关.

Then it passes. But I can't change the server's behaviour, and I want the client classes to have well-named properties in the C# idiom. I can't use LINQ to JSON since I want it to work outside of Silverlight. It looks like the XmlElement tags are having no effect. I don't know where I got the idea they were relevant at all, they probably aren't.

你如何在 JavaScriptSerializer 中进行字段名称映射?完全可以做到吗?

How do you do field name mapping in JavaScriptSerializer? Can it be done at all?

推荐答案

我再次尝试使用 DataContractJsonSerializer 类.这解决了它:

I took another try at it, using the DataContractJsonSerializer class. This solves it:

代码如下:

using System.Runtime.Serialization;

[DataContract]
public class DataObject
{
    [DataMember(Name = "user_id")]
    public int UserId { get; set; }

    [DataMember(Name = "detail_level")]
    public string DetailLevel { get; set; }
}

测试是:

using System.Runtime.Serialization.Json;

[TestMethod]
public void DataObjectSimpleParseTest()
{
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DataObject));

        MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(JsonData));
        DataObject dataObject = serializer.ReadObject(ms) as DataObject;

        Assert.IsNotNull(dataObject);
        Assert.AreEqual("low", dataObject.DetailLevel);
        Assert.AreEqual(1234, dataObject.UserId);
}

唯一的缺点是我必须将 DetailLevel 从枚举更改为字符串 - 如果您保留枚举类型,则 DataContractJsonSerializer 期望读取数值并失败.有关更多详细信息,请参阅 DataContractJsonSerializer 和 Enums.

The only drawback is that I had to change DetailLevel from an enum to a string - if you keep the enum type in place, the DataContractJsonSerializer expects to read a numeric value and fails. See DataContractJsonSerializer and Enums for further details.

在我看来这很糟糕,尤其是当 JavaScriptSerializer 正确处理它时.这是您尝试将字符串解析为枚举的例外情况:

In my opinion this is quite poor, especially as JavaScriptSerializer handles it correctly. This is the exception that you get trying to parse a string into an enum:

System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type DataObject. The value 'low' cannot be parsed as the type 'Int64'. --->
System.Xml.XmlException: The value 'low' cannot be parsed as the type 'Int64'. --->  
System.FormatException: Input string was not in a correct format

像这样标记枚举不会改变这种行为:

And marking up the enum like this does not change this behaviour:

[DataContract]
public enum DetailLevel
{
    [EnumMember(Value = "low")]
    Low,
   ...
 }

这似乎也适用于 Silverlight.

This also seems to work in Silverlight.

这篇关于JavaScriptSerializer.Deserialize - 如何更改字段名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆