Triển khai JsonConverter lớp được cấp: lớp CustomCreationConverter nên được sử dụng làm lớp cơ sở để tạo đối tượng tùy chỉnh tùy chỉnh.
Dự thảo phiên bản của bộ chuyển đổi (xử lý lỗi có thể được cải thiện khi bạn muốn):
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
}
Khách hàng mã:
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);
Xin lưu ý: có một vụ va chạm tiềm năng giữa tên tài sản và chìa khóa tên của từ điển.
Nguồn
2013-02-15 12:41:18
Cảm ơn bạn. Chỉ có một bổ sung: Tôi nghĩ rằng tốt hơn có được các thuộc tính từ JsonContract '(JsonObjectContract) serializer.ContractResolver.ResolveContract (typeof (Test))'. Sử dụng cách này có thể nhận được các giá trị JsonPropertyAttribute. – Nataly