Json.NET:序列化图表序列只会返回"type-name"



我正在尝试使用NewtonSoft.Json序列化System.Windows.Forms.DataVisualization.Charting.Series,我得到的只是该系列的名称及其类型。我正在尝试获取该系列的所有属性,以便保存人员设置的系列设置。

我对序列化还很陌生,但我在其他对象方面也取得了一些成功,所以我不确定这里发生了什么。以下是我所做的(举个例子(:

JsonConvert.SerializeObject(new Series("TestName"), Formatting.Indented);

退货:"Series-TestName"

我希望有更像的东西

{
"AxisLabel": "",
"BackGradientStyle": None,
"BackHatchStyle": None
...
}

感谢@dbc为我指出这里讨论的NoTypeConverterJsonConverter<T>,我得以解决我的问题。

我做了一个NoTypeConverterJsonConverter<T>的修改版本,它采用了一个类型列表来应用NoType转换:

public class NoTypeConverterJsonConverter : JsonConverter
{
private NoTypeConverterContractResolver Resolver = new NoTypeConverterContractResolver();
/// <summary>
/// The types where the default typeconverter will not be used
/// </summary>
public List<Type> TypesToOverride
{
get { return Resolver.DefaultedTypes; }
set { Resolver.DefaultedTypes = value; }
}
private class NoTypeConverterContractResolver : DefaultContractResolver
{
/// <summary>
/// The types where the default typeconverter will not be used
/// </summary>
public List<Type> DefaultedTypes = new List<Type>();
protected override JsonContract CreateContract(Type objectType)
{
// if its in the listed types
if (DefaultedTypes.Any(t => t.IsAssignableFrom(objectType)))
{
// create a default contract
JsonObjectContract contract = base.CreateObjectContract(objectType);
// Null out the converter to not use the default typeconverter.
contract.Converter = null; 
return contract;
}
// if it decends from a list
else if (typeof(IList<>).IsAssignableFrom(objectType))
{
// create a contract from the object, avoiding any presets(?)
JsonObjectContract contract = this.CreateObjectContract(typeof(IList<>));
//contract.Converter = null; // Also null out the converter to prevent infinite recursion.
return contract;
}
try
{
// use default contract creator
return base.CreateContract(objectType);
}
catch (Exception ex)
{
// see if it can be treated as a list
if (typeof(IList<>).IsAssignableFrom(objectType))
{
// create a contract from the object, avoiding any presets(?)
JsonObjectContract contract = this.CreateObjectContract(typeof(IList<>));
//contract.Converter = null; // Also null out the converter to prevent infinite recursion.
return contract;
}
throw ex;
}

}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
return property;
}
}
/// <summary>
/// Default Constructor
/// </summary>
/// <param name="skippedTypes"></param>
public NoTypeConverterJsonConverter(List<Type> skippedTypes = null)
{
if (skippedTypes != null)
{
TypesToOverride = skippedTypes;
}
}
public override bool CanConvert(Type objectType)
{
return TypesToOverride.Any(t => t.IsAssignableFrom(objectType));
}
public override object ReadJson(
JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JsonSerializer.CreateDefault(
new JsonSerializerSettings { ContractResolver = Resolver }
).Deserialize(reader, objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JsonSerializer.CreateDefault(
new JsonSerializerSettings { ContractResolver = Resolver }
).Serialize(writer, value);
}
}

我还发现像DataPointCollection这样的集合往往处理得很差,只返回计数,所以我添加了IList部分:

// see if it can be treated as a list
if (typeof(IList<>).IsAssignableFrom(objectType))
{
// create a contract from the object, avoiding any presets(?)
JsonObjectContract contract = this.CreateObjectContract(typeof(IList<>));
//contract.Converter = null; // Also null out the converter to prevent infinite recursion.
return contract;
}

然后代码的使用方式如下:

// The types to not use the default typeconverter
List<Type> skippedTypes = new List<Type>()
{
typeof(DataPoint),
typeof(DataPointCustomProperties),
typeof(SmartLabelStyle)
};
// create converter
NoTypeConverterJsonConverter converter = new NoTypeConverterJsonConverter(skippedTypes);
// use the converter to serialize a series
string seriesstr = JsonConvert.SerializeObject(series, Formatting.Indented, 
new JsonSerializerSettings()
{
Converters = new List<JsonConverter> { converter }
});
// deserialise using the same converter
Series series2 = JsonConvert.DeserializeObject<Series>(seriesstr, new JsonSerializerSettings()
{
Converters = new List<JsonConverter> { converter }
});

实际上,只需将任何给你带来麻烦的类型添加到列表中,它通常会对其进行排序。

相关内容

最新更新