C# JsonConvert.SerializeObject+;类型转换器=StackOverflowException

C# JsonConvert.SerializeObject+;类型转换器=StackOverflowException,c#,C#,我在方法JsonTypeConverter.ConvertTo中获得了StackOverflowException 调用Project.Settings.Default.Save()时 我认为这是因为方法JsonConvert.SerializeObject检测模型类型上的类型转换器并在内部调用它 写这个的正确方法是什么?(我能想到的唯一方法是在设置中存储字符串,并手动执行序列化/反序列化…) 公共类JsonTypeConverter:TypeConverter { #类型转换器的区域覆盖 公共

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

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

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

公共类JsonTypeConverter:TypeConverter
{
#类型转换器的区域覆盖
公共覆盖布尔CanConvertFrom(ITypeScriptorContext上下文,类型sourceType)
{
返回sourceType==typeof(字符串);
}
公共覆盖布尔CanConvertTo(ITypeDescriptorContext上下文,类型destinationType)
{
返回destinationType==typeof(字符串);
}
公共重写对象ConvertFrom(ITypeDescriptorContext上下文、CultureInfo区域性、对象值)
{
if(值为字符串strValue){
返回JsonConvert.DeserializeObject(strValue);
}
返回base.ConvertFrom(上下文、区域性、值);
}
公共重写对象转换为(ITypeDescriptorContext上下文、CultureInfo区域性、对象值、类型destinationType)
{
if(destinationType==typeof(string)&&value为TModel模型){
返回JsonConvert.SerializeObject(model,Formatting.None);
}
返回base.ConvertTo(上下文、区域性、值、destinationType);
}
#端区
}
名称空间模型{
[TypeConverter(typeof(JsonTypeConverter))]
[设置Serializeas(设置Serializeas.String)]
公共类数据模型{
公共字符串值{get;set;}
}
}
“属性/设置.设置”的内容:

<?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
和设置序列化程序都在使用
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);
    }
}
公共类JsonTypeConverter:TypeConverter
{
/*你们班的其他同学*/
公共重写对象ConvertFrom(ITypeDescriptorContext上下文、CultureInfo区域性、对象值)
{
if(值为字符串strValue)
{
返回JsonConvert.DeserializeObject(strValue,新的JsonSerializerSettings
{
ContractResolver=新的CustomContractResolver(),
});
}
返回base.ConvertFrom(上下文、区域性、值);
}
公共重写对象转换为(ITypeDescriptorContext上下文、CultureInfo区域性、对象值、类型destinationType)
{
if(destinationType==typeof(string)&&value为TModel模型)
{
返回JsonConvert.SerializeObject(模型,新JsonSerializerSettings
{
ContractResolver=新的CustomContractResolver(),
});
}
返回base.ConvertTo(上下文、区域性、值、destinationType);
}
}     
类CustomContractResolver:DefaultContractResolver
{
受保护的重写JsonContract CreateContract(类型objectType)
{
if(typeof(DataModel).IsAssignableFrom(objectType))
{
返回此.CreateObjectContract(objectType);
}
返回base.CreateContract(objectType);
}
}
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);
    }
}