使用GetJsonAsync获取元组列表

时间:2019-11-20 07:16:27

标签: c# asp.net-core json.net asp.net-core-webapi blazor

我正在开发Blazor应用程序。我有一个返回List<Tuple<string,int>>的API方法。

邮递员中的API响应:

[
    {
        "Item1": "1",
        "Item2": 1
    },
    {
        "Item1": "24",
        "Item2": 2
    }
]

剃须刀页面中的API调用:

private object dataSource;

protected override async Task OnInitializedAsync() {
    dataSource = await Http.GetJsonAsync<List<Tuple<string,int>>>("/Api/Default/GetProjectsList");
}

但是,我收到以下错误:

Deserialization of reference types without parameterless constructor is not supported.

我了解错误。

是否有GetJsonAsync可以解析的泛型类型,也可以从API方法返回该泛型类型?

或者有没有办法解析这个元组?请帮我。

3 个答案:

答案 0 :(得分:3)

这是使用新的System.Text.Json时的限制。参见official docs

  

不支持对无类型构造函数的引用类型进行反序列化。

由于Tuple<string,int>没有无参数构造函数,因此失败。

作为一种解决方案,您可以使用经典的Newtonsoft.Json来反序列化元组:

var resp = await Http.GetStringAsync("/Api/Default/GetProjectsList");
var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Tuple<string,int>>>(resp);



foreach(var i in list){
    Console.WriteLine("--------");
    Console.WriteLine(i.Item1);
    Console.WriteLine(i.Item2);
    Console.WriteLine("--------");
}

答案 1 :(得分:2)

(当前)使用内置System.Text序列化程序时,如果没有无参数构造函数,则无法反序列化类型。

但是,您始终可以创建一个小的包装对象:

public class MyItem
{ 
   public MyItem {}
   public string Item1 {get; set;}
   public int Item2 {get; set;}
}

and then 

 await Http.GetJsonAsync<List<MyItem>>(...)

答案 2 :(得分:1)

您可以尝试使用Workaround并使用ValueTuple

简而言之,System.Text.Json当前不支持反序列化ValueTypeTuple。这是因为要反序列化ValueTypeTuple需要反序列化字段。(当前反序列化不支持字段,请参见github issue

解决方法是创建一个自定义Json转换器以及与内核相对应的Json Convertor工厂,而不是在asp.net core全局json选项中注册此Json Converter。在这种情况下,您无需创建包装器类。