Determine if Json results is object or array

Using Json.NET, you could do this:

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>();
}

I found that the accepted solution using Json.NET is a bit slow for large JSON files.
It appears that the JToken API is performing too many memory allocations.
Here is a helper method that uses the JsonReader API with the same result:

public static List<T> DeserializeSingleOrList<T>(JsonReader jsonReader)
{
    if (jsonReader.Read())
    {
        switch (jsonReader.TokenType)
        {
            case JsonToken.StartArray:
                return new JsonSerializer().Deserialize<List<T>>(jsonReader);

            case JsonToken.StartObject:
                var instance = new JsonSerializer().Deserialize<T>(jsonReader);
                return new List<T> { instance };
        }
    }

    throw new InvalidOperationException("Unexpected JSON input");
}

The usage:

public HttpResponseMessage Get(string id)
{
    var filePath = $"{AssemblyDirectory}/../Data/phones/{id}.json";

    using (var json = File.OpenText(filePath))
    using (var reader = new JsonTextReader(json))
    {
        var phones = DeserializeSingleOrList<Phone>(reader);

        return Request.CreateResponse<List<Phone>>(HttpStatusCode.OK, phones);
    }
}

Asthetically I like the answer @dcastro gave better. But, if you are generating a JToken object, you can also just use the Type enum property of the token. It's possibly less expensive then doing an object type comparison, as the Type property has already been determined.

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.Object)
{
    Phone phone = token.ToObject<Phone>();
}
else
{
    Console.WriteLine($"Neither, it's actually a {token.Type}");
}

If you are using .NET Core 3.1, you can use the following check on the JsonElement object.

using System.Text.Json;

public void checkJsonElementType(JsonElement element) {
    switch (element.ValueKind)
    {
        case JsonValueKind.Array:
            // it's an array
            // your code in case of array
            break;
        case JsonValueKind.Object:
            // it's an object
            // your code in case of object
            break;
        case JsonValueKind.String:
            // it's an string
            // your code in case of string
            break;
       .
       .
       .
    }
}

Allowed values of JsonValueKind are Array, False, Null, Number, Object, String, True, Undefined