总结:使用 JavaScriptSerializer.Deserialize 时,如何将 JSON 数据中的字段名称映射到 .Net 对象的字段名称?
加长版:我从服务器 API 收到以下 JSON 数据(未在 .Net 中编码)
{"user_id":1234, "detail_level":"low"}
我有以下 C# 对象:
[Serializable]
public class DataObject
{
[XmlElement("user_id")]
public int UserId { get; set; }
[XmlElement("detail_level")]
public DetailLevel DetailLevel { get; set; }
}
其中 DetailLevel 是一个以“Low”作为值之一的枚举。
此测试失败:
[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 数据更改为
{"userid":1234, "detaillevel":"low"}
然后它通过了。但我无法更改服务器的行为,并且我希望客户端类在 C# 惯用语中具有命名良好的属性。我不能使用 LINQ to JSON,因为我希望它在 Silverlight 之外工作。看起来 XmlElement 标签没有效果。我完全不知道我从哪里得到它们相关的想法,它们可能不相关。
如何在 JavaScriptSerializer 中进行字段名映射?能做到吗?
最佳答案
我又试了一次,使用 DataContractJsonSerializer类(class)。这样就解决了:
代码如下所示:
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 and Enums了解更多详情。
在我看来,这很糟糕,尤其是当 JavaScriptSerializer 正确处理它时。这是您尝试将字符串解析为枚举的异常(exception)情况:
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
并且像这样标记枚举不会改变这种行为:
[DataContract]
public enum DetailLevel
{
[EnumMember(Value = "low")]
Low,
...
}
这似乎也适用于 Silverlight。
关于c# - JavaScriptSerializer.Deserialize - 如何更改字段名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1100191/