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

标签 c# json parsing serialization javascriptserializer

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

相关文章:

c# - 如何使用 Entity Framework 6 从数据库中获取数据

java - HtmlUnit 获取页面错误

excel - 停止 Excel 日期解析

c# - 使用列表中的字符串创建 DropDownList<string>

c# - 抑制生成代码的结果

javascript - 从键名获取数组的元素对象

php - json 返回字符串而不是对象

json - 使用Kotlinx.Serialization解析嵌套的JSON

c# - 阻止 & 符号变成 Windows 窗体绑定(bind)的助记符/加速器

java - 从 servlet 创建自定义 json