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

查看:1449
本文介绍了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 ?

加长版:我有以下的JSON数据来我从服务器API(未在.net codeD)

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#中的成语良好的命名属性。因为我希望它的Silverlight外面工作,我不能使用LINQ JSON。它看起来像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:

在code是这样的:

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预计读取数值和失败。见<一href=\"http://stackoverflow.com/questions/794838/datacontractjsonserializer-and-enums\">DataContractJsonSerializer和枚举的进一步的细节。

在我看来这是相当差,特别是作为的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天全站免登陆