Более эффективный способ десериализации строки JSON до 1 из 2 типов объектов - PullRequest
0 голосов
/ 02 июля 2019

У меня есть данные, хранящиеся в поле БД, действующем как кеш от вызова API.Эти данные относятся к типу:

  • MyObject
  • List<MyObject>

В настоящее время у меня есть следующий код, который использует NewtonSoft.JSON длявзять строку и (на основе успешной десериализации) определить, к какому из этих типов относится строка.

var _lstObj = new List<MyObject>();
var _obj = new MyObject();
bool isList = false;

try
{
    var n = JsonConvert.DeserializeObject<List<MyObject>>(cacheString);
    if(n!=null && n.Count()>0)
    {
        _lstObj = n;
        isList = true;
    }
}
catch(Exception e)
{
    isList = false;
}


if (!isList)
{
    try 
    {
        var x = JsonConvert.DeserializeObject<MyObject>(cacheString);
        if (x != null && x.Data != null)
        {
            _obj = x;
        }
    }
    catch(Exception e) { }
}

Это кажется довольно громоздким ... есть ли лучший способ сделать это?

У меня всегда будет строка для входящих данных.

Это будет только один из этих двух типов.

Ответы [ 3 ]

3 голосов
/ 02 июля 2019

Это должно работать:

var obj = (JToken)JsonConvert.DeserializeObject(cacheString);
if (obj.Type == JTokenType.Array)
{
    var result = obj.ToObject<List<MyObject>>();
}
else
{
    var result = obj.ToObject<MyObject>();
}
3 голосов
/ 02 июля 2019

Сначала следует проверить, является ли строка json списком.

if (cacheString.StartsWith("["))
{
    var myList = JsonConvert.DeserializeObject<List<MyObject>>(cacheString);
}
else
{
    var myObject = JsonConvert.DeserializeObject<MyObject>(cacheString);
}
1 голос
/ 02 июля 2019

Я бы использовал объект расширения, чтобы вы могли продолжать добавлять свойства, если вам нравится динамически.

        dynamic exp = new ExpandoObject();

        try
        {
            exp.isList = true;
            exp.value = JsonConvert.DeserializeObject<List<MyObject>>(cacheString);
        }
        catch (Exception e)
        {
            exp.isList = false;
            exp.value = JsonConvert.DeserializeObject<MyObject>(cacheString);
        }

, но в идеале я бы кэшировал объект как список независимо от того, один он или много.

...