JavaScriptSerializer.Deserialize - 如何改变字段名 [英] JavaScriptSerializer.Deserialize - how to change field names
问题描述
摘要:使用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屋!