4

シリアル化と逆シリアル化に素晴らしい Newtonsoft json.Net (バージョン 4.5.7.15008) ライブラリを使用しています。

私はしたいと思います:

  1. .Databagシリアライズ時にプロパティを無視します。
  2. 書き込まれた 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);
    }
4

0 に答える 0