码迷,mamicode.com
首页 > Web开发 > 详细

Newton.Json中JsonConverter的使用

时间:2020-12-30 10:42:50      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:ide   ssi   public   err   信息保存   writer   alt   ted   重写   

一、使用场景:

有两个类都继承了同一个抽象类:

/// <summary>
/// 沙盒基类
/// </summary>
abstract class SandBoxGanmeBase
{
    /// <summary>
    /// 名称
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 版本
    /// </summary>
    public string Version { get; set; }

    /// <summary>
    /// 可以驾驶
    /// </summary>
    public bool CanDrive { get { return true; } }
}

/// <summary>
/// GTA
/// </summary>
class GTA5 : SandBoxGanmeBase
{
    public bool HasHotCoffe { get; set; }
}

/// <summary>
/// Cyberpunk2077
/// </summary>
class Cyberpunk2077 : SandBoxGanmeBase
{
    public bool CanModifyDingDing { get { return true; } }
}

 把信息保存入json:

string sJsonFile = AppDomain.CurrentDomain.BaseDirectory + "games.json";

IList<SandBoxGanmeBase> games = new List<SandBoxGanmeBase>();

games.Add(new GTA5()
{
    Name = "GTA5",
    Version = "1.53",
    HasHotCoffe = true
});

games.Add(new Cyberpunk2077()
{
    Name = "Cyberpunk2077",
    Version = "1.06"
});

string sJson = JsonConvert.SerializeObject(games, Formatting.Indented);

if (!File.Exists(sJsonFile))
    File.Create(sJsonFile).Close();

using (TextWriter chsTw = new StreamWriter(sJsonFile))
{
    chsTw.WriteLine(sJson);
chsTw.Flush();
}

games.json 内容:

技术图片

 一般的,使用如下代码读取 games.json:

 string sJsonFile = AppDomain.CurrentDomain.BaseDirectory + "games.json";

 string sJson = string.Empty;
 using (StreamReader sr = new StreamReader(sJsonFile))
     sJson = sr.ReadToEnd();

 IList<SandBoxGanmeBase> games = JsonConvert.DeserializeObject<IList<SandBoxGanmeBase>>(sJson);

会 catch ex 报错:

技术图片

因为,抽象类在Newton.Json 反序列化时,无法确定继承抽象类的实例,因此,我们必须要告诉 Newton.Json:你需要使用哪个类来进行反序列化,因此,JsonConverter 应运而生。

 

二、自定义 JsonConverter

class MyJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(SandBoxGanmeBase).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            var jsonObject = JObject.Load(reader);
            object target = null;
            JToken gameName;
            if (jsonObject.TryGetValue("Name", out gameName))
            {
                switch (gameName.ToString())
                {
                    case "GTA5":
                        target = new GTA5();
                        break;
                    case "Cyberpunk2077":
                        target = new Cyberpunk2077();
                        break;
                }
            }
            serializer.Populate(jsonObject.CreateReader(), target);
            return target;
        }
        catch (Exception ex)
        {
            throw new Exception("解析异常:" + ex.Message);
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {

    }
}

修改读取 game.json 代码为:

string sJsonFile = AppDomain.CurrentDomain.BaseDirectory + "games.json";

string sJson = string.Empty;
using (StreamReader sr = new StreamReader(sJsonFile))
    sJson = sr.ReadToEnd();

IList<SandBoxGanmeBase> games = JsonConvert.DeserializeObject<IList<SandBoxGanmeBase>>(sJson, new MyJsonConverter());

反序列化正常:

技术图片

 

三、拓展----用特性方式使用 JsonConverter

1、反序列化

SandBoxGanmeBase 增加特性,修改为:

/// <summary>
/// 沙盒基类
/// </summary>
[JsonConverter(typeof(MyJsonConverter))]
abstract class SandBoxGanmeBase
{
    ...
}

读取 game.json 方法还原为:

...

IList<SandBoxGanmeBase> games = JsonConvert.DeserializeObject<IList<SandBoxGanmeBase>>(sJson);

2、序列化

仅为 SandBoxGanmeBase 增加了特性,再进行序列化时,序列化的 Json 字符串为空,修改 MyJsonConverter,增加 CanWrite 属性:

class MyJsonConverter : JsonConverter
{
    ...public override bool CanWrite { get { return false; } }

    ...public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {

    }
}

这样,在序列化对象时,就使用 Newton.Json 默认的 WriteJson 而不是使用 MyJsonConvert 中重写的 WriteJson。

Newton.Json中JsonConverter的使用

标签:ide   ssi   public   err   信息保存   writer   alt   ted   重写   

原文地址:https://www.cnblogs.com/seanyan/p/14184995.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!