Подтвердить что ты не робот

Определить, являются ли результаты Json объектом или массивом

Я использую .net web api, чтобы получить json и вернуть его на передний конец для angular. Json может быть либо объектом, либо массивом. В настоящее время мой код работает только для массива, а не для объекта. Мне нужно найти способ tryparse или определить, является ли содержимое объектом или массивом.

Вот мой код

    public HttpResponseMessage Get(string id)
    {
        string singleFilePath = String.Format("{0}/../Data/phones/{1}.json", AssemblyDirectory, id);
        List<Phone> phones = new List<Phone>();
        Phone phone = new Phone();
        JsonSerializer serailizer = new JsonSerializer();

        using (StreamReader json = File.OpenText(singleFilePath))
        {
            using (JsonTextReader reader = new JsonTextReader(json))
            {
                //if array do this
                phones = serailizer.Deserialize<List<Phone>>(reader);
                //if object do this
                phone = serailizer.Deserialize<Phone>(reader);
            }
        }

        HttpResponseMessage response = Request.CreateResponse<List<Phone>>(HttpStatusCode.OK, phones);

        return response;
    }

Вышеупомянутое может быть не лучшим способом сделать это. Его, где я сейчас.

4b9b3361

Ответ 1

Используя Json.NET, вы можете сделать это:

string content = File.ReadAllText(path);
var token = JToken.Parse(content);

if (token is JArray)
{
    IEnumerable<Phone> phones = token.ToObject<List<Phone>>();
}
else if (token is JObject)
{
    Phone phone = token.ToObject<Phone>();
}

Ответ 2

Астетически мне нравится ответ, который @dcastro дал лучше. Но если вы генерируете объект JToken, вы также можете просто использовать свойство enum Type токена. Возможно, это дешевле, чем сравнение типов объектов, поскольку свойство Type уже определено.

https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JTokenType.htm

//...JToken token
if (token.Type == JTokenType.Array)
{
    IEnumerable<Phone> phones = token.ToObject<List<Phone>>();
}
else if (token.Type == JTokenType.JObject)
{
    Phone phone = token.ToObject<Phone>();
}
else
{
    Console.WriteLine($"Neither, it actually a {token.Type}");
}

Ответ 3

Вы всегда можете включить десериализацию внутри блока try/catch. Просто попытайтесь десериализовать его как массив внутри блока try, и он будет генерировать исключение, если это тип объекта.

try
{
    //if array do this
    phones = serailizer.Deserialize<List<Phone>>(reader);
}
catch //Deserialization of array failed - must be object
{
    //if object do this
    phone = serailizer.Deserialize<Phone>(reader);
}

Я знаю, что некоторые люди будут хмуриться от использования try/catch, как это, но я считаю, что это эффективно.