C#根据条件反序列化Json

时间:2016-07-11 12:40:53

标签: c# json

{
    "timeAgo": "6 minutes ago",
    "time": "07/11/2016 07:00 AM",
    "alertId": 145928,
    "details": {


    },
    "priority": 10,
    "type": 2,
    "isClosed": 0,
    "notesCount": 0,
    "patientAccountId": 680,
    "isRead": 0
  }

我想基于int值'type'反序列化json,这样,我希望细节是不同的类型

public class Notification
{
    public string timeAgo { get; set; }
    public string time { get; set; }
    public int alertId { get; set; }
    public object details { get; set; }
    public int priority { get; set; }
    public int type { get; set; }
    public int isClosed { get; set; }
    public int notesCount { get; set; }
    public int patientAccountId { get; set; }
    public int isRead { get; set; }
}

如果type = 1,则对象'details'的类型为A,如果type = 2,'details'的类型为B,依此类推。类型约有25个值。

所以,稍后我可以做类似的事情:

Notification n = ....
if (type == 1)
{
    A a = (a) n.details;

3 个答案:

答案 0 :(得分:1)

如果您的json没有JSON中包含的适当类型,这将有效。

如果你的实际结构更复杂,可能需要调整,但我设法让你的样本工作。

var instance = Newtonsoft.Json.JsonConvert.DeserializeObject<Notification>(
    js,
    new ItemConverter());

public class ItemA : Item { }
public class ItemB : Item { }
public class Item { }

public class Notification
{
    public string timeAgo { get; set; }
    public string time { get; set; }
    public int alertId { get; set; }
    public Item details { get; set; }
    public int priority { get; set; }
    public int type { get; set; }
    public int isClosed { get; set; }
    public int notesCount { get; set; }
    public int patientAccountId { get; set; }
    public int isRead { get; set; }
}

public class ItemConverter : JsonConverter
{
    private Type currentType;
    public override bool CanConvert(Type objectType)
    {
        return typeof(Item).IsAssignableFrom(objectType) || objectType == typeof(Notification);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject item = JObject.Load(reader);
        if (item["type"] != null)
        {
            // save the type for later.
            switch (item["type"].Value<int>())
            {
                case 1:
                    currentType = typeof(ItemA);
                    break;
                default:
                    currentType = typeof(ItemB);
                    break;
            }
            return item.ToObject<Notification>();
        }

        // use the last type you read to serialise.
        return item.ToObject(currentType);
    }

    public override void WriteJson(JsonWriter writer,
        object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:0)

您可以使用特殊的JSON序列化设置,例如

var jsonSerializerSettings = new JsonSerializerSettings()
    {
        TypeNameHandling = TypeNameHandling.All
    };

类型名称将与实际的“详细信息”数据一起存储,因此您可以将其反序列化为有效的类。

var instance = new Notification
        {
            details = new Details
            {
                Name = "Hello"
            }
        };
var json = JsonConvert.SerializeObject(instance, jsonSerializerSettings);

制作了json

{"$type":"Application.Notification, Application","details":{"$type":"Application.Details, Application","Name":"Hello"}}

答案 2 :(得分:-1)

var json = "{\r\n    \"timeAgo\": \"6 minutes ago\",\r\n    \"time\": \"07/11/2016 07:00 AM\",\r\n    \"alertId\": 145928,\r\n    \"details\": {\r\n\r\n\r\n    },\r\n    \"priority\": 10,\r\n    \"type\": 2,\r\n    \"isClosed\": 0,\r\n    \"notesCount\": 0,\r\n    \"patientAccountId\": 680,\r\n    \"isRead\": 0\r\n  }";
Notification data = JsonConvert.DeserializeObject<Notification>(json);

var type=1;
if (type == 1)
   {
     string[] a = data.details as string[];
   }