摘要:在使用JavaScriptSerializer.Deserialize时,如何将JSON数据中的字段名Map到.Net对象的字段名?
较长版本:我从服务器API(未在.Net中编码)接收到以下JSON数据
{"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);
}
最后两个Assert失败,因为这些字段中没有数据。
{"userid":1234, "detaillevel":"low"}
然后它通过了。但是我不能改变服务器的行为,并且我希望客户端类具有C#习惯中命名良好的属性。我不能使用LINQ to JSON,因为我希望它在Silverlight之外工作。看起来XmlElement标记没有任何作用。我不知道我从哪里得到它们相关的想法,它们很可能没有。
在JavaScriptSerializer中如何进行字段名Map?它能完全完成吗?
9条答案
按热度按时间bcs8qyzn1#
我又试了一次,使用DataContractJsonSerializer类,这样就解决了这个问题:
代码如下所示:
测试是:
唯一的缺点是我不得不将DetailLevel从枚举更改为字符串-如果您保留枚举类型,DataContractJsonSerializer将读取数值,但会失败。有关详细信息,请参见DataContractJsonSerializer and Enums。
在我看来,这是相当糟糕的,特别是当JavaScriptSerializer正确地处理它时。这是你试图将字符串解析成枚举时遇到的异常:
像这样标记枚举不会改变这种行为:
这似乎也适用于Silverlight。
e5njpo682#
通过创建一个定制的JavaScriptConverter,你可以将任何名称Map到任何属性,但是这需要手工编码Map,这并不理想。
然后你可以这样反序列化:
9njqaruj3#
Json.NET将执行您想要的操作(免责声明:我是这个包的作者).它支持阅读DataContract/DataMember属性以及它自己的属性来改变属性名称.还有StringEnumConverter类用于将枚举值序列化为名称而不是数字.
sdnqo3pr4#
JavaScriptSerializer
中没有重命名属性的标准支持,但是您可以很容易地添加自己的属性:DataObject
类将变为:我知道这可能有点晚,但认为其他人想使用
JavaScriptSerializer
而不是DataContractJsonSerializer
可能会欣赏它。vptzau2j5#
创建一个继承自JavaScriptConverter的类。然后必须实现以下三项内容:
方法-
1.序列化
1.反序列化
物业-
1.支持的类型
当需要对序列化和反序列化过程进行更多控制时,可以使用JavaScriptConverter类。
Here is a link for further information
svujldwt6#
我已经使用了using Newtonsoft.Json,如下所示。创建一个对象:
现在调用下面的方法序列化为Json对象,如下所示。
3zwtqj6y7#
对于那些出于某种原因不想使用Newtonsoft Json.Net或
DataContractJsonSerializer
的人(我想不出任何一个:)),这里有一个JavaScriptConverter
的实现,它支持DataContract
和enum
到string
的转换-注意:此
DataContractJavaScriptConverter
将仅处理在其所在的程序集中定义的DataContract
类。如果需要来自单独程序集的类,请在静态构造函数中相应地修改_supportedTypes
列表。这可用作以下用途-
DataObject
类看起来像这样-请注意,此解决方案不处理
DataMember
属性支持的EmitDefaultValue
和Order
属性。fkaflof68#
我的要求包括:
我最终的解决方案是使用SimpleJson(https://github.com/facebook-csharp-sdk/simple-json)。
尽管您可以通过nuget包安装它,但我在项目中只包含了一个SimpleJson.cs文件(带有MIT许可证)并引用了它。
希望这能帮到什么人。
n7taea2i9#
下面是Tom Maher答案的通用版本,它会自动将
DataObject
中的所有嵌套属性类型注册到转换器中,以便它们可以使用JsonPropertyAttribute
。使用方法: