gpt4 book ai didi

c# - JsonConvert.SerializeObject + TypeConverter = StackOverflowException

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

我在方法 JsonTypeConverter.ConvertTo 中得到 StackOverflowException调用 Project.Settings.Default.Save()

我认为这是因为方法 JsonConvert.SerializeObject 检测模型类型上的类型转换器并在内部调用它 ...

正确的写法是什么? (我能想到的唯一方法是在设置中存储字符串并手动进行序列化/反序列化...)

public class JsonTypeConverter<TModel> : TypeConverter
{
#region Overrides of TypeConverter

public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string);
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string strValue) {
return JsonConvert.DeserializeObject<TModel>(strValue);
}

return base.ConvertFrom(context, culture, value);
}

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string) && value is TModel model) {
return JsonConvert.SerializeObject(model, Formatting.None);
}

return base.ConvertTo(context, culture, value, destinationType);
}

#endregion
}

namespace Model {

[TypeConverter(typeof(JsonTypeConverter<DataModel>))]
[SettingsSerializeAs(SettingsSerializeAs.String)]
public class DataModel {
public string Value { get; set; }
}
}

“Properties/Settings.settings”的内容:

<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Builder.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="DataSource" Type="Model.DataModel" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>

PS:对这个问题标题有什么建议吗?

最佳答案

问题是 JsonConverter 和 Settings Serializer 都在使用 TypeConverter 属性来告诉它们如何序列化对象。当 JsonConverter 尝试序列化对象时,它将最终通过您的自定义转换器再次调用自身并最终导致堆栈溢出。

要在您的转换器中解决此问题,您必须告诉 JsonConverter 不要使用类型 TypeConverterAttribute 并且只执行默认对象序列化。这是我发现实现此目的的方法:

public class JsonTypeConverter<TModel> : TypeConverter
{
/* rest of your class ... */

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string strValue)
{
return JsonConvert.DeserializeObject<TModel>(strValue, new JsonSerializerSettings
{
ContractResolver = new CustomContractResolver(),
});
}

return base.ConvertFrom(context, culture, value);
}

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string) && value is TModel model)
{
return JsonConvert.SerializeObject(model, new JsonSerializerSettings
{
ContractResolver = new CustomContractResolver(),
});
}

return base.ConvertTo(context, culture, value, destinationType);
}
}

class CustomContractResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
if (typeof(DataModel).IsAssignableFrom(objectType))
{
return this.CreateObjectContract(objectType);
}
return base.CreateContract(objectType);
}
}

关于c# - JsonConvert.SerializeObject + TypeConverter = StackOverflowException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46186666/

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