gpt4 book ai didi

c# - 将 Newtonsoft.Json 与嵌套的自定义类一起使用

转载 作者:太空宇宙 更新时间:2023-11-03 12:34:20 33 4
gpt4 key购买 nike

我需要序列化一些自定义对象以存储信息。但是,我正在努力将这些对象从序列化的 JSON 字符串反序列化回其原始对象形式。

序列化后的字符串看起来没问题:

[
{
"MyStringArray": [
"stringInput1",
"stringInput2"
],
"MyCharArray": [
"a",
"b",
"c",
"."
],
"MyString": "dummy",
"MyClass3Object": [
{
"MyString": "ListInput1"
},
{
"MyString": "ListInput2"
}
]
}
]

但是,当我重建原始的 MyClass1 对象时,该列表本来应该有一个条目,但它填充的是空值而不是相应的数据。关于可能发生的事情有什么想法吗?在此先感谢您的集思广益:)

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.IO;
using System.Text.RegularExpressions;

namespace JsonTesting
{
class Program
{
static void Main(string[] args)
{

MyClass1 c1 = new MyClass1();
c1.AddInfo();

string toJsonString = JsonConvert.SerializeObject(c1, Formatting.Indented,
new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Include });
File.WriteAllText(@"C:\temp\dumpJsonText.txt",toJsonString);
MyClass1 fromJson = JsonConvert.DeserializeObject<MyClass1>(toJsonString);
Console.ReadLine();

}
}


public class MyClass1 : List<MyClass2> {
public MyClass1() { }
public void AddInfo() {
this.Add(new MyClass2(new string[] { "stringInput1", "stringInput2" },
new char[] { 'a', 'b', 'c', '.' },
"dummy",
new List<MyClass3>() { new MyClass3("ListInput1", new Regex(@"[A-Z]")), new MyClass3("ListInput2", new Regex(@"[0-9]")) }
));
}
}

public class MyClass2
{
private string[] _myStringArray = null;
private char[] _myCharArray = null;
private string _myString = null;
private List<MyClass3> _myClass3Object = null;

public MyClass2() { }

public MyClass2(string[] myStringArray, char[] myCharArray, string myString, List<MyClass3> myClass3Object)
{
_myStringArray = myStringArray;
_myCharArray = myCharArray;
_myString = myString;
_myClass3Object = myClass3Object;
}

public string[] MyStringArray { get { return _myStringArray; } }
public char[] MyCharArray { get { return _myCharArray; } }
public string MyString { get { return _myString; } }
public List<MyClass3> MyClass3Object { get { return _myClass3Object; } }

}

public class MyClass3 {

private Regex _myRegex;
private string _myString = null;
public MyClass3() { }
public MyClass3(string myString, Regex myRegex) {

_myString = myString;
_myRegex = myRegex;
}

public string MyString{ get {return _myString;} }

}

}

最佳答案

您的类 MyClass2MyClass3 是只读的。为了让 Json.NET 反序列化只读类型,您必须提供 custom JsonConverter手动反序列化并构造该类型的一个实例,或者提供一个参数化构造函数,其参数名称与属性名称模数大小写相匹配。您已经创建了必要的构造函数,因此已经完成了一半。

但是你的类型也有无参数的构造函数。那么,Json.NET 调用了哪个构造函数呢?对于序列化为 JSON object 的不可枚举类型, 以下规则适用:

  1. 如果[JsonConstructor]在构造函数上设置,请使用该构造函数。

  2. 接下来,在 full trust only ,当 MemberSerialization.Fields 被应用,或者 [Serializable] 被应用并且 DefaultContractResolver.IgnoreSerializableAttribute == false , 特殊方法 FormatterServices.GetUninitializedObject()用于分配对象。 没有调用任何类型的构造函数。

    (这是不常见的不常见情况。)

  3. 接下来,如果有公共(public)无参数构造函数,就使用它。

  4. 接下来,如果存在私有(private)无参数构造函数并且设置 ConstructorHandling.AllowNonPublicDefaultConstructor启用时,使用私有(private)无参数构造函数。

  5. 接下来,如果有单个公共(public)参数化构造函数,则使用该构造函数。

  6. 如果无法满足上述所有条件,Json.NET 将无法构造该类型的实例。除非自定义转换器可用,否则在反序列化期间会抛出异常。

因此,无参数构造函数优先于参数化构造函数。要强制使用参数化构造函数,请使用 [JsonConstructor] 标记它们,如上所述:

public class MyClass3
{
private Regex _myRegex;
private string _myString = null;

public MyClass3() { }

[JsonConstructor]
// The argument names must match the property names modulo case for Json.NET to deserialize the properties successfully.
public MyClass3(string myString, Regex myRegex)
{
_myString = myString;
_myRegex = myRegex;
}

public string MyString { get { return _myString; } }

public Regex MyRegex { get { return _myRegex; } }
}

或者,您可以删除无参数构造函数,因为它显然不存在于您问题的第一个版本中。然后对 MyClass2 进行相同的更改。现在您的类型将成功反序列化。

注意 Json.NET 有一个 built-in converter用于序列化 Regex

样本 fiddle .

关于c# - 将 Newtonsoft.Json 与嵌套的自定义类一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41551530/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com