确定 JSON 结果是对象还是数组
本文关键字:数组 对象 JSON 结果是 确定 | 更新日期: 2024-10-25 00:13:44
我正在使用.net web api来获取json并将其返回到前端以进行Angular。json 可以是对象或数组。我的代码目前仅适用于数组而不是对象。我需要找到一种方法来尝试解析或确定内容是对象还是数组。
这是我的代码
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;
}
以上可能不是最好的方法。它就是我现在的位置。
使用 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>();
}
我发现使用 Json.NET 的接受解决方案对于大型 JSON 文件来说有点慢.JToken
API 似乎执行了太多内存分配.
下面是使用具有相同结果的 JsonReader
API 的帮助程序方法:
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");
}
用法:
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);
}
}
从美学上讲,我喜欢@dcastro给出的答案。但是,如果要生成 JToken 对象,也可以只使用令牌的 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.Object)
{
Phone phone = token.ToObject<Phone>();
}
else
{
Console.WriteLine($"Neither, it's actually a {token.Type}");
}
如果您使用的是 .NET Core 3.1,则可以对 JsonElement
对象使用以下检查。
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;
.
.
.
}
}
允许的JsonValueKind
值Array, False, Null, Number, Object, String, True, Undefined