Serialize/Deserialize dynamic property name using JSON.NET

♀尐吖头ヾ 提交于 2020-01-10 05:57:25

问题


I have the following class:

public class MyRequest
{
    public string Type {get;set;}
    public string Source {get;set;}
}

I would like to serialize/deserialize the value for Source from the JSON field named the value of Type, for example:

{
    "type": "bank",
    "bank": "Some value"
}

or

{
    "type": "card",
    "card": "Some value"
}

Where both bind to the Source property.


回答1:


You could create a custom JsonConverter to handle the dynamic property name:

public class MyRequestConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(MyRequest);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        string type = (string)jo["type"];
        MyRequest req = new MyRequest
        {
            Type = type,
            Source = (string)jo[type ?? ""]
        };
        return req;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        MyRequest req = (MyRequest)value;
        JObject jo = new JObject(
            new JProperty("type", req.Type),
            new JProperty(req.Type, req.Source));
        jo.WriteTo(writer);
    }
}

To use the converter, add a [JsonConverter] attribute to your class like this:

[JsonConverter(typeof(MyRequestConverter))]
public class MyRequest
{
    public string Type { get; set; }
    public string Source { get; set; }
}

Here is a working round-trip demo: https://dotnetfiddle.net/o7NDTV




回答2:


I would write custom serialization/deserialization methods

var req1 = new MyRequest() { Type = "card", Source = "SomeValue" };
var json = Serialize(req1);
var req2 = Deserialize<MyRequest>(json);

string Serialize<T>(T obj)
{
    var jObj = JObject.FromObject(obj);
    var src = jObj["Source"];
    jObj.Remove("Source");
    jObj[(string)jObj["Type"]] = src;
    return jObj.ToString(Newtonsoft.Json.Formatting.Indented);
}

T Deserialize<T>(string json)
{
    var jObj = JObject.Parse(json);
    var src = jObj[(string)jObj["Type"]];
    jObj.Remove((string)jObj["Type"]);
    jObj["Source"] = src;
    return jObj.ToObject<T>();
} 



回答3:


My solution is: First create APIResultModel class:

public class APIResultModel<T> where T: APIModel, new()
{

    public string ImmutableProperty { get; set; }

    public T Result { get; set; }

    public APIResultModel<T> Deserialize(string json)
    {
        var jObj = JObject.Parse(json);
        T t = new T();
        var result = jObj[t.TypeName()];
        jObj.Remove(t.TypeName());
        jObj["Result"] = result;
        return jObj.ToObject<APIResultModel<T>>();
    }
}

Second create APIModel abstract Class:

public abstract class APIModel
{
    public abstract string TypeName();
}

Third create dynamic content Model class:

public class MyContentModel: APIModel
{
    public string Property {get; set;}
    public override string TypeName()
    {
        return "JsonKey";
    }
}

When you need to deserialize a json string:

var jsonModel = new APIResultModel<MyContentModel>();
jsonModel = jsonModel.Deserialize(json);
MyContentModel dynimacModel = jsonModel.Result;

The Deserialize function is come from @Eser



来源:https://stackoverflow.com/questions/47043028/serialize-deserialize-dynamic-property-name-using-json-net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!