Nat*_*aly 35 c# serialization json.net
我正在使用Json.Net进行序列化.我有一个带有词典的类:
public class Test
{
public string X { get; set; }
public Dictionary<string, string> Y { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我可以以某种方式序列化此对象以获取以下JSON
{
"X" : "value",
"key1": "value1",
"key2": "value2"
}
Run Code Online (Sandbox Code Playgroud)
其中"key1","key2"是字典中的键?
Bri*_*ers 49
如果您使用Json.Net 5.0.5或更高版本以及你愿意从改变你的字典的类型Dictionary<string, string>来Dictionary<string, object>,然后一个简单的方法来完成你想要的是将添加[JsonExtensionData]属性您喜欢这本字典属性:
public class Test
{
public string X { get; set; }
[JsonExtensionData]
public Dictionary<string, object> Y { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后,标记字典的键和值将被序列化为父对象的一部分.奖励是它也适用于反序列化:JSON中与类成员不匹配的任何属性都将放入字典中.
实现JsonConverter派生类:CustomCreationConverter类应该用作基类来创建自定义对象.
转换器的草稿版本(可以根据需要改进错误处理):
internal class TestObjectConverter : CustomCreationConverter<Test>
{
#region Overrides of CustomCreationConverter<Test>
public override Test Create(Type objectType)
{
return new Test
{
Y = new Dictionary<string, string>()
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteStartObject();
// Write properties.
var propertyInfos = value.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos)
{
// Skip the Y property.
if (propertyInfo.Name == "Y")
continue;
writer.WritePropertyName(propertyInfo.Name);
var propertyValue = propertyInfo.GetValue(value);
serializer.Serialize(writer, propertyValue);
}
// Write dictionary key-value pairs.
var test = (Test)value;
foreach (var kvp in test.Y)
{
writer.WritePropertyName(kvp.Key);
serializer.Serialize(writer, kvp.Value);
}
writer.WriteEndObject();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jsonObject = JObject.Load(reader);
var jsonProperties = jsonObject.Properties().ToList();
var outputObject = Create(objectType);
// Property name => property info dictionary (for fast lookup).
var propertyNames = objectType.GetProperties().ToDictionary(pi => pi.Name, pi => pi);
foreach (var jsonProperty in jsonProperties)
{
// If such property exists - use it.
PropertyInfo targetProperty;
if (propertyNames.TryGetValue(jsonProperty.Name, out targetProperty))
{
var propertyValue = jsonProperty.Value.ToObject(targetProperty.PropertyType);
targetProperty.SetValue(outputObject, propertyValue, null);
}
else
{
// Otherwise - use the dictionary.
outputObject.Y.Add(jsonProperty.Name, jsonProperty.Value.ToObject<string>());
}
}
return outputObject;
}
public override bool CanWrite
{
get { return true; }
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
客户代码:
var test = new Test
{
X = "123",
Y = new Dictionary<string, string>
{
{ "key1", "value1" },
{ "key2", "value2" },
{ "key3", "value3" },
}
};
string json = JsonConvert.SerializeObject(test, Formatting.Indented, new TestObjectConverter());
var deserializedObject = JsonConvert.DeserializeObject<Test>(json);
Run Code Online (Sandbox Code Playgroud)
请注意:属性名称和字典的键名之间可能存在冲突.