相关文章推荐
潇洒的茴香  ·  [Eclipse+PyDev]ImportE ...·  10 月前    · 
温柔的木耳  ·  Remediate anonymous ...·  1 年前    · 

1、问题描述

C#使用Newtonsoft.Json将 一般对象 序列化和反序列化为json时,一般使用 SerializeObject() DeserializeObject() 即可。
但是,当对象中包含一个自定义集合对象时,仅仅使用 DeserializeObject() 无法正确实现反序列化。
有可能报错:

无法将类型为“Newtonsoft.Json.Linq.JObject”的对象强制转换

2、代码说明

直接用一段示例代码,进行说明。

2.1 准备阶段

示例准备3个类:
Action 类:表示一个动作。

class Action
    public Action()
    public Action(string name, int step)
        m_name = name;
        m_step = step;
    public override string ToString()
        return $"Action Name:{m_name}, Step: {m_step.ToString()}";
    private string m_name; // 动作名称
    private int m_step; // 动作步骤
    public string Name { get => m_name; set => m_name = value; }
    public int Step { get => m_step; set => m_step = value; }

ActionCollection 类:表示一个动作的集合类。

class ActionCollection : CollectionBase
    public void Add(Action action)
        this.InnerList.Add(action);

Cat 类:猫类,Cat 对象包含一个 ActionCollection 类实例。

class Cat
    private string m_name; // 猫的名字
    private ActionCollection m_actions; // 具备的动作集合
    public Cat()
    public Cat(string name, ActionCollection ac)
        this.m_name = name;
        this.m_actions = ac;
    public string Name { get => m_name; set => m_name = value; }
    public ActionCollection Actions { get => m_actions; set => m_actions = value; }

2.2 序列化

使用 SerializeObject() 方法将一个 Cat 对象序列化为Json,并存储到文件中。

/// <summary>
/// 序列化一个Cat对象到Json
/// </summary>
/// <param name="cat"></param>
/// <param name="jsonPath"></param>
public static void Save(Cat cat, string jsonPath)
    string jsonString = JsonConvert.SerializeObject(cat);
    File.WriteAllText(jsonPath, jsonString);

2.3 反序列化

简单地使用 DeserializeObject() 方法从json文件中读取json字符串,并反序列化为一个 Cat 对象。

/// <summary>
/// 反序列化(错误方法)
/// </summary>
/// <param name="jsonPath"></param>
public static Cat Load(string jsonPath)
    string jsonString = File.ReadAllText(jsonPath);
    Cat cat = JsonConvert.DeserializeObject<Cat>(jsonString);
    return cat;

使用测试代码进行调试,发现会报错:

无法将类型为“Newtonsoft.Json.Linq.JObject”的对象强制转换为Action。
在这里插入图片描述

原因说明:

简单地使用 DeserializeObject() 方法进行反序列化时,只会将 ActionCollection 集合类实例中的元素反序列化为一个JObject对象。
JObject对象无法隐式转换为Action类对象,因而会报错。

解决方案:
由于使用 DeserializeObject() 方法无法正确地将“集合对象字段”的元素反序列化出来。因此,需要手动修正。

代码如下:

/// <summary>
/// 反序列化(正确方法)
/// </summary>
/// <param name="jsonPath"></param>
/// <returns></returns>
public static Cat LoadJson(string jsonPath)
    string jsonString = File.ReadAllText(jsonPath);
    Cat cat = JsonConvert.DeserializeObject<Cat>(jsonString);
    ActionCollection actions = new ActionCollection();
    foreach(var item in cat.Actions)
        string itemString = item.ToString();
        Action ac = JsonConvert.DeserializeObject<Action>(itemString);
        actions.Add(ac);
    cat.Actions = actions;
    return cat;

再次使用测试代码进行调试,可以发现问题解决。
在这里插入图片描述

3、测试代码

如果需要测试报错,需要取消“错误方法取出猫”的注释。

static void Main(string[] args)
    // 准备一只猫
    Action run = new Action("Running", 2);
    Action jump = new Action("Jump", 2);
    ActionCollection actions = new ActionCollection();
    actions.Add(run);
    actions.Add(jump);
    Cat helloKitty = new Cat("HelloKitty", actions);
    // 将猫放入json
    string jsonPath = "cat.json";
    Save(helloKitty, jsonPath);
     错误方法取出猫
    //Cat helloKittyClone = Load(jsonPath);
    //Console.WriteLine(helloKittyClone.Name);
    //foreach (Action x in helloKittyClone.Actions)
    //    Console.WriteLine(x.ToString());
    // 正确方法取出猫
    Cat helloKittyCloneX = LoadJson(jsonPath);
    Console.WriteLine(helloKittyCloneX.Name);
    foreach (Action x in helloKittyCloneX.Actions)
        Console.WriteLine(x.ToString());

代码附件:Github传送门

以上为C#使用Newtonsoft.Json反序列化时遇到的一个问题。如果有更好的解决方案,欢迎留言交流。

1、问题描述C#使用Newtonsoft.Json将 一般对象 序列化和反序列化为json时,一般使用 SerializeObject() 和 DeserializeObject() 即可。但是,当对象中包含一个自定义集合对象时,仅仅使用DeserializeObject() 无法正确实现反序列化。有可能报错:无法将类型为“Newtonsoft.Json.Linq.JObject”的对象强制转换2、代码说明直接用一段示例代码,进行说明。2.1 准备阶段示例准备3个类:Action 类:
首先,将json串转为一个JObject对象: JObject jo = (JObject)JsonConvert.DeserializeObject(CurrentSelectedItemReq); 这个JObject是一个“值对”类型,比如说我们的json串是这样: rows:[ {NumIid:001}, {PicUrl:xxx.png}, {Title:xxxxx}, {Price:xxx}, {OuterId:xxxx} {NumIid:002}, JObject _jObject = JObject.Parse("{'ID':'001','Mark':'Hello Word'}");   StringBuilder str = new StringBuilder();   foreac...
“itemcoord”:{“x”:0,“y”:100,“width”:40,“height”:20}, “words”:[ {“character”:“手”,“confidence”:90.9}, {“character”:“机”,“confidence”......
JObject 1.Json是这样的{title:123,body:456,list:{title:'这是一个标题',body:'what'}}2.我要将其中几项都搞出来,代码:static void Main(string[] args) string str = "{title:123,body:456,list:{title:'这是一个标题',body:'what'}}"
c#无法类型为“Newtonsoft.Json.Linq.JArray”的对象强制转换为’System.Collections.Generic.List` 无法类型为“Newtonsoft.Json.Linq.JArray”的对象强制转换为’System.Collections.Generic.List` 当json返回的格式为:{[’***’,’***’,’***’,…]}这种数据类型类似于List但又不等同时list时,该如何转换为List类型呢? 解决方法:先将该json转换为JArray,
在做开发的时候,很多数据交换都是以json格式传输的。而使用Json的时候,我们很多时候会涉及到几个序列化对象使用Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity的 各版本2.0到4.5,类型分net,netstandard,portable,根据自己需要可以进行筛选使用
Newtonsoft.Json的Unity转换器 该软件包包含往返于常见Unity类型的转换器。 类型,例如Vector2,Vector3,Matrix4x4,四元数,颜色,甚至ScriptableObject等等。 (请参阅的) Newtonsoft.Json软件包 此程序包需要在项目中包含Newtonsoft.Json.dll文件。 因此,它不必与我的jillejr.newtonsoft.json-for-unity软件包一起使用! 我认识到Unity生态系统中有太多的Newtonsoft.Json分支和变体。 该软件包可以与以下任何一项结合使用: 我自己的JamesNK原始牛顿软件的分支.Json回购: (推荐) SaladLab的叉子: ParentElement的资产商店软件包: ://www.parentelement.com/assets/json_
无法类型为“System.Int32”的对象强制转换类型“System.String”。 说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。  异常详细信息: System.InvalidCastException: 无法类型为“System.Int32”的对象强制
在VS2008下使用Newtonsoft.Json进行JSON的序列化与反序列化可以按照以下步骤进行: 1. 在项目中添加Newtonsoft.Json的引用,可以通过NuGet包管理器安装Newtonsoft.Json。 2. 创建需要序列化的对象,并使用JsonConvert.SerializeObject方法将对象序列化为JSON字符串。 Person person = new Person Name = "Tom", Age = 30 string json = JsonConvert.SerializeObject(person); 3. 将JSON字符串反序列化对象,可以使用JsonConvert.DeserializeObject方法。 string json = "{\"Name\":\"Tom\",\"Age\":30}"; Person person = JsonConvert.DeserializeObject<Person>(json); 其中,Person是需要反序列化对象类型。 注意:在使用Newtonsoft.Json时,需要使用Newtonsoft.Json命名空间。