シリアル化と逆シリアル化に素晴らしい Newtonsoft json.Net (バージョン 4.5.7.15008) ライブラリを使用しています。
私はしたいと思います:
.Databag
シリアライズ時にプロパティを無視します。- 書き込まれた JSON をカスタマイズします。最初にデフォルトの JSON を取得し、それを変更して、変更された JSON を結果に書き込みます。
これらは私のクラスです:
public interface ISimpleDatabag
{
string Databag { get; set; }
}
[JsonConverter(typeof(JsonDataBagCreationConverter<Department>))]
public class Department : ISimpleDatabag
{
[JsonIgnoreAttribute]
public string Databag { get; set; }
public string Name { get; set; }
public Telephone[] Phones { get; set; }
}
[JsonConverter(typeof(JsonDataBagCreationConverter<Telephone>))]
public class Telephone : ISimpleDatabag
{
[JsonIgnoreAttribute]
public string Databag { get; set; }
public string Name { get; set; }
public string AreaCode { get; set; }
public string Number { get; set; }
}
public class JsonDataBagCreationConverter<T> : JsonConverter where T : ISimpleDatabag, new()
{
// Json.Net version 4.5.7.15008
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// problem 1
string jsonAsDefault = ""; // The json that would have been written have I not overridden WriteJson. How?
// problem 1.a: Ignore the Databag property when writing the json.
string myChangedJson = jsonAsDefault + "WhatEverIWant";
// problem 2
// Write myChangedJson to the resulting json string instead of jsonAsDefault
// try
//serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; // Otherwise self referencing loop detected, but then...
// JObject jobj = JObject.FromObject(value, serializer); //... Stack overflow
// jobj.WriteTo(writer);
// try
// writer.WriteValue(value); // "Unsupported type: Department
// try
//serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; // Otherwise self referencing loop detected, but then...
// serializer.Serialize(writer, value); // ...Stack overflow
// try
// base.WriteJson(writer, value, serializer); base class is abstract
}
protected T Create(Type objectType, JObject jsonObject)
{
return new T();
}
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jsonObject = JObject.Load(reader);
var target = Create(objectType, jsonObject);
serializer.Populate(jsonObject.CreateReader(), target); // Will call this function recursively for any objects that have JsonDataBagCreationConverter as attribute
((ISimpleDatabag)target).Databag = jsonObject.ToString(); // This is where custom data is stored in databag
return target;
}
}
public class IgnoreDataBagContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (property.PropertyName.ToLower() == "databag")
{
property.Ignored = true;
return property;
}
return property;
}
}
そして呼び出し:
public Form1()
{
InitializeComponent();
string jsonInput = "{\"Name\": \"Seek4\" , \"CustomDepartmentData\": \"This is custom department data\", \"Phones\":[ {\"Name\": \"A\", \"AreaCode\":444, \"Number\":11111111} ,{\"Name\": \"B\", \"AreaCode\":555, \"Number\":987987987}, {\"Name\": \"C\", \"AreaCode\":222, \"Number\":123123123, \"CustomPhoneData\": \"This is custom phone data\"} ] }";
Department objDepartment = JsonConvert.DeserializeObject<Department>(jsonInput); // Yes, it works well
objDepartment.Name = "Seek4Cars";
string json = ToSeek4Json(objDepartment); // This is my problem: Ignore Databag property and control the output json for each property
}
public static string ToSeek4Json(object objectToConvertToJson)
{
JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
IgnoreDataBagContractResolver contractResolver = new IgnoreDataBagContractResolver();
serializerSettings.ContractResolver = contractResolver;
return JsonConvert.SerializeObject(objectToConvertToJson, Formatting.None, serializerSettings);
}