使用System.Text.Json反序列化时System.Type实例不支持序列化报错如何解决
报错原因
你在注入IGenericHttpClient时指定了泛型参数为System.Type,导致调用GetJsonAsync方法时,反序列化的目标类型被推导为List<System.Type>。
System.Text.Json出于安全考虑默认禁止
System.Type类型的序列化、反序列化操作:恶意构造的JSON payload可以通过注入危险类型触发远程代码执行漏洞,因此框架直接拦截了这类操作,抛出你遇到的报错。
解决办法
你的业务需求是反序列化选中模型类的记录列表,而非Type类型的列表,现有泛型HttpClient的用法不符合动态类型的场景,可选择以下两种方案修复:
方案1:新增动态类型反序列化重载(适合需要完整模型实例的场景)
首先修改GenericHttpClient.cs,新增支持运行时指定返回类型的非泛型方法:
public async ValueTask<object> GetJsonAsync(string url, Type resultType) { using HttpResponseMessage response = await _client.GetAsync(url); ValidateResponse(response); var content = await response.Content.ReadAsStringAsync(); // 传入动态生成的目标类型完成反序列化 return JsonSerializer.Deserialize(content, resultType, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }); }
然后修改MyPage.razor.cs的调用逻辑:
// 调整注入的HttpClient为非泛型实现,根据你自己的DI注册调整即可 [Inject] private GenericHttpClient HttpClient { get; set; } private Type SelectedType { get; set; } // 注意修正原方法名的拼写错误:OnTypeChnage → OnTypeChange private void OnTypeChange(ChangeEventArgs args) { string FullName = "My.Models." + args.Value.ToString(); // 注意修正原拼写错误:Assemble → Assembly SelectedType = Assembly.GetExecutingAssembly().GetType(FullName, false); } private async Task OnPropertyChange(ChangeEventArgs args) { // 动态构造列表类型:List<SelectedType> Type listType = typeof(List<>).MakeGenericType(SelectedType); // 调用重载方法,传入动态类型完成反序列化 var list = await HttpClient.GetJsonAsync($"/api/{SelectedType.Name}/all", listType); // 后续可直接通过反射遍历list,读取指定属性的值 }
方案2:接口直接返回属性值列表(更轻量的方案)
如果只需要获取选中属性的所有值,不需要完整的模型实例,可以调整后端接口逻辑,直接返回指定属性的一维数组,前端固定用List<object>或者List<string>接收即可,无需处理动态类型:
// 前端调用示例,泛型参数固定为object,无需动态生成类型 var valueList = await HttpClient.GetJsonAsync<List<object>>($"/api/{SelectedType.Name}/propertyValues?propertyName={args.Value}");
内容的提问来源于stack exchange,提问作者Nb777
相关产品推荐
相关产品推荐

