Json.Net序列化类名称而不是内部属性 [英] Json.Net serializing the class name instead of the internal properties

查看:86
本文介绍了Json.Net序列化类名称而不是内部属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是代码:

public class ParameterDictionary : Dictionary<HydroObjectIdentifier, string>
{

    public void WriteToJson(string jsonFilePath)
    {
        string json = Newtonsoft.Json.JsonConvert.SerializeObject(this, formatting: Newtonsoft.Json.Formatting.Indented);
        System.IO.File.WriteAllText(jsonFilePath, json);
    }

}

public struct HydroObjectIdentifier
{

    public string Name { get; set; }
    public string TypeName { get; set; }

    public HydroObjectIdentifier(string name, string typeName)
    {
        this.Name = name;
        this.TypeName = typeName;
    }

}

...这就是Json的结果.请注意,它显示的是类名RSEngine.HydroObjectIdentifier而不是其参数,这在我的代码中是没有用的.

...and this is the Json result. Notice that it shows the class name RSEngine.HydroObjectIdentifier instead of its parameters, which was not intended in my code.

{
  "RSEngine.HydroObjectIdentifier": [
    {
      "myString"
    },
    ...

如评论中所述,预期的行为是将Name和TypeName写入json中,而不是类的名称.

As explained in the comments, the intended behavior is to write Name and TypeName into the json, instead of the name of the class.

推荐答案

看到这种现象的原因是因为您使用复杂的对象(HydroObjectIdentifier)作为Dictionary中的键.在JSON中,根据规范,对象键必须始终为字符串.当Json.Net尝试序列化字典时,它会发现您的密钥是 not 字符串.由于它需要一个字符串,因此只需在您的类上调用ToString()即可. C#中ToString()的默认实现返回类型的名称,在您的情况下为RSEngine.HydroObjectIdentifier.

The reason you are seeing this behavior is because you are using your complex object (HydroObjectIdentifier) as the key in a Dictionary. In JSON, object keys must always be strings, per the spec. When Json.Net tries to serialize the dictionary, it sees that your keys are not strings. Since it needs a string, it simply calls ToString() on your class. The default implementation of ToString() in C# returns the name of the type, which in your case is RSEngine.HydroObjectIdentifier.

如果您实现自己的ToString()方法(如另一个答案中所建议),那么您可以随心所欲地解决问题.但是,这种方法的缺点是您将无法将JSON反序列化回字典中.那是因为Json.Net不能使用相反的"FromString"方法来将序列化的密钥从字符串转换回标识符类.如果您需要使用JSON(序列化和反序列化)进行完整往返,那么您将需要其他解决方案.

If you implement your own ToString() method, as was suggested in another answer, then you can make the key whatever you want to get around the issue. However, the downside of this approach is that you will not be able to deserialize the JSON back into your dictionary. That is because there is no converse "FromString" method that Json.Net can use to convert the serialized key from a string back into your identifier class. If you need to be able to go the full round trip with your JSON (serialize and deserialize) then you will need a different solution.

在Json.Net中有两种可能的方法来处理复杂的字典键:

There are a couple of possible ways to handle complex dictionary keys in Json.Net:

  1. 为标识符类实施 TypeConverter Json.Net序列化指南中.有关详细信息,请参见如何:在MSDN中实现类型转换器.在实现类型转换器之后,您将需要使用[TypeConverter]属性标记您的类,以便Json.Net知道要使用它.
  2. 对于更改后的字典,使用自定义 JsonConverter 键值对如何写入JSON.有关该方法的示例,请参见如何序列化从Dictionary派生的类.
  1. Implement a TypeConverter for your identifier class, as is mentioned in the Json.Net Serialization Guide. See How to: Implement a Type Converter in MSDN for details. After implementing the type converter, you will need to mark your class with a [TypeConverter] attribute so Json.Net knows to use it.
  2. Use a custom JsonConverter for the dictionary which changes how the key-value pairs are written to the JSON. See How To Serialize a class that derives from a Dictionary for an example of that approach.

这篇关于Json.Net序列化类名称而不是内部属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆