serialization - Json.NET:序列化图表系列只返回“类型名称”
问题描述
我正在尝试使用 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);
}
}
我还发现 Collections likeDataPointCollection
往往被处理得很差,只返回计数,所以我添加了 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 }
});
实际上,只需将任何给您带来麻烦的类型添加到该列表中,它通常就会将其整理出来。
推荐阅读
- haskell - 使用 Aeson 从输入 args 解码 json 的问题
- javascript - 反应本机注册按钮问题
- javascript - 脚本标签无法加载资源状态 404
- react-native - Visual Studio 代码错误中的 React-Native 代码
- android - Android中的共享首选项和内部存储有什么区别?数据存储在哪里?
- php - 两个表的内连接 [更新]
- node.js - Mongodb连接数组内的元素
- c# - 是否可以使用自定义属性来强制执行方法签名
- android - 使用 Intent 将整个回收站视图传递给另一个活动的最佳方法是什么?
- postgresql - 在 2 列上查询日期/时间