我遇到了一個不尋常的問題。這可能不是一個非常現實的場景,但是這是我已經接觸到的,所以請耐心等待。將任意json響應轉換爲「東西」列表
我有一個返回Json的API,我使用Json.NET來處理Json響應。問題是,API可以返回一些東西,我必須能夠通過以下方式反序列化響應:
- API可以返回單個Json對象。在這種情況下,我必須將其反序列化爲
ExpandoObject
並將其放入List<dynamic>
。 - API可以返回null和undefined等,在這種情況下,我必須返回一個空列表。
- API可以返回單個原始值,如Json字符串或Json浮點型。在這種情況下,我必須將其反序列化爲適當的.NET類型,並將其放入
List<dynamic>
並返回該類型。 - 該API可以返回一個Json數組。在這種情況下,我要反序列化陣列爲
List<dynamic>
:- 數組中的元素可以是JSON對象,在這種情況下,我必須再次向他們反序列化爲
ExpandoObject
,並把它們在列表中。 - 元素也可以是原始值。在這種情況下,我必須將它們反序列化爲適當的.NET類型並將它們放入列表中。
- 數組中的元素可以是JSON對象,在這種情況下,我必須再次向他們反序列化爲
根據我的研究,這裏就是我想出迄今:
protected IQueryable<dynamic> TestMethod(string r)
{
using (StringReader sr = new StringReader(r))
using (JsonTextReader reader = new JsonTextReader(sr))
{
if (!reader.Read())
{
return new List<ExpandoObject>().AsQueryable();
}
switch (reader.TokenType)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.Undefined:
return new List<ExpandoObject>().AsQueryable();
case JsonToken.StartArray:
return JsonConvert.DeserializeObject<List<ExpandoObject>>(r).AsQueryable();
case JsonToken.StartObject:
return DeserializeAs<ExpandoObject>(r);
case JsonToken.Integer:
return DeserializeAs<long>(r);
case JsonToken.Float:
return DeserializeAs<double>(r);
// other Json primitives deserialized here
case JsonToken.StartConstructor:
// listing other not processed tokens
default:
throw new InvalidOperationException($"Token {reader.TokenType} cannot be the first token in the result");
}
}
}
private IQueryable<dynamic> DeserializeAs<T>(string r)
{
T instance = JsonConvert.DeserializeObject<T>(r);
return new List<dynamic>() { instance }.AsQueryable();
}
問題是與最後一顆子彈點。在開關情況下,當解串器遇到StartArray
標記時,它會嘗試將json反序列化爲List<ExpandoObject>
,但如果數組包含整數,則不能將其反序列化爲ExpandoObject
。
任何人都可以給我一個簡單的解決方案來支持兩種情況:Json對象數組爲List<ExpandoObject>
和Json基元數組到他們各自的列表?
這些來自同一端點嗎? – Dispersia
是的,相同的端點。我知道這不是很現實,但我們假設這是一個給定的。 –
簡單的解決方案是重構您的端點。 –