c# - JavaScriptSerializer.Deserialize - 如何更改字段名称

总结:使用 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。

https://stackoverflow.com/questions/1100191/

相关文章:

c# - 使用 Web API 返回匿名类型

java - 在 Spring 中配置 ObjectMapper

java - jackson + build 者模式?

javascript - 在没有 jQuery 的情况下在 node.js 上合并或合并 JSON

java - 错误 415 不支持的媒体类型 : POST not reaching REST if

json - REST API 最佳实践 : args in query string vs in

java - gson.toJson() 抛出 StackOverflowError

javascript - 排序对象属性和 JSON.stringify

java - 将 PostgreSQL JSON 列映射到 Hibernate 实体属性

json - 从 JQuery.ajax 成功数据中解析 JSON