gpt4 book ai didi

.net - 使用[JsonConverter]属性时,我的JsonConverter类中的StackOverflowException

转载 作者:行者123 更新时间:2023-12-04 12:08:16 27 4
gpt4 key购买 nike

我有一个要尝试序列化的测试类:

public class Testing
{
private string _name;
private string _firstname = "firstname";
public string _lastname;
private DateTime _datenow = DateTime.Now;
public DateTime _birthdate = DateTime.Now;

public string Name { get { return _name; } set { _name = value; } }
}

我正在使用自定义的 JsonConverter处理测试类的序列化:
public class TestingConverter : JsonConverter
{
private Type[] _types = new Type[] { typeof(Testing)};

/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
try
{
JToken t = JToken.FromObject(value); //This is what i want to do
//rest of code
}
catch (Exception ex)
{
Console.Write(ex.Message);
throw;
}
}

public override bool CanRead
{
get
{
return false;
}
}
}

如果我通过将转换器传递给 JsonSerializer对象来执行序列化,则可以正常工作:
Testing t = new Testing();
t._lastname = "USER LAST NAME";
JsonSerializer p = JsonSerializer.CreateDefault();
p.Converters.Add(new TestingConverter());

using (StreamWriter file = File.CreateText("output.json"))
using (JsonTextWriter writer = new JsonTextWriter(file))
{
p.Serialize(writer, t);
}

但是,如果我改为用 [JsonConverter]属性标记我的测试类:
[JsonConverter(typeof(TestingConverter))]
public class Testing
{
private string _name;
private string _firstname = "firstname";
public string _lastname;
private DateTime _datenow = DateTime.Now;
public DateTime _birthdate = DateTime.Now;

public string Name { get { return _name; } set { _name = value; } }
}

并像这样序列化:
Testing t = new Testing();
t._lastname = "USER LAST NAME";
JsonSerializer p = JsonSerializer.CreateDefault();


using (StreamWriter file = File.CreateText("output.json"))
using (JsonTextWriter writer = new JsonTextWriter(file))
{
p.Serialize(writer, t);
}

我的 TestingConverter类被调用了,但是它在 JToken.FromObject(value)方法处进入了递归循环,最后以 StackOverflowException崩溃。

谁能告诉我为什么会这样吗?我想念什么?

最佳答案

当您将转换器的一个实例传递给序列化器时,只有该序列化器的实例才知道该转换器。在转换器内部,当您调用JToken.FromObject(value)时,它将使用其他序列化程序实例将值转换为JToken。该实例不知道您的转换器,因此按预期使用Json.Net的默认序列化逻辑。一切都很好。

另一方面,如果您在类型上放置[JsonConverter]属性以指示该类型已由您的转换器处理,那么现在所有序列化器实例都知道您的转换器。转换器内部对JToken.FromObject(value)的调用将启动一个新的序列化器实例;该实例看到它应该使用您的转换器来处理此对象类型,因此它以递归方式调用您的转换器。重复此过程,直到堆栈空间用完为止。

如果要使用[JsonConverter]属性,则需要更改转换器的内部,以避免递归调用链。通常,这涉及手动处理类型的所有单个属性。例如,以下版本将与应用的属性一起使用:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Testing t = (Testing)value;
JObject jo = new JObject();
jo.Add("name", t.Name);
jo.Add("lastname", t._lastname);
jo.Add("birthdate", t._birthdate);
jo.WriteTo(writer);
}

关于.net - 使用[JsonConverter]属性时,我的JsonConverter类中的StackOverflowException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22407321/

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