System.Text.Json JsonSerializer:不支持“System.Type”实例的序列化和反序列化
Posted
技术标签:
【中文标题】System.Text.Json JsonSerializer:不支持“System.Type”实例的序列化和反序列化【英文标题】:System.Text.Json JsonSerializer: Serialization and deserialization of 'System.Type' instances are not supported 【发布时间】:2021-10-05 07:55:07 【问题描述】: 当我尝试使用 `System.Text.Json JsonSerializer` 进行反序列化时,出现与安全性相关的错误。我想实现什么? 我想让用户控制我的数据库中的一些记录,所以使用可以遵循这个场景:
1- 用户可以选择我的类库的模型。 2- 选择一个类后,用户将从该类中选择一个属性(归档)。 3-用户将获得所选属性的值列表。 4- 最后一步现在不在这里,用户可以编辑一个特定的值。
这是我的一段代码:
MyPage.razor.cs:
[Inject]
private IGenericHttpClient<Type> HttpClient get; set;
private Type SelectedType get; set;
// First select a class [Class library] from html Select
private void OnTypeChnage(ChangeEventArgs args)
string FullName = "My.Models." + args.Value.ToString();
// Create type of selected class
SelectedType = Assemble.GetType(FullName, false);
//Call api to get all fields of this class
private async Task OnPropertChange(ChangeEventArgs args)
var list = await
HttpClient.GetJsonAsync($"/api/SelectedType.Name/all");
GenericHttpClient.cs
public async ValueTask<List<T>> GetJsonAsync(string url)
using HttpResponseMessage response = await _client.GetAsync(url);
ValidateResponse(response);
var conetnt = await response.Content.ReadAsStringAsync();
//I got the error down
return JsonSerializer.Deserialize<List<T>>(conetnt, new JsonSerializerOptions() PropertyNameCaseInsensitive=true);
【问题讨论】:
【参考方案1】:出于安全原因,System.Text.Json 不支持 Type 类。您将完整的程序集名称作为字符串发送,然后再次尝试在客户端构造类型。
【讨论】:
嗨@Mayur,我知道Type class
会导致问题,请您帮我实现您所说的“您将完整的程序集名称作为字符串发送,然后再次尝试构造类型在客户端。”
您能否详细说明您的用例/流程?
好的,我会添加一些解决方案,但效率不是很高,所以请阅读它,如果你能做得更好,那就太好了!。
我认为我们遇到了 XY 问题。使用动态,尤其是在 HTTP 请求等中,并不是很有用。您不妨使用字典。如果您能说明您的职能/业务目标,这将有助于我们更快地找到解决方案。【参考方案2】:
public async ValueTask<List<T>> GetJsonAsync(string url)
这甚至不会编译,因为没有指定方法签名的通用信息。
而且,您的问题可能来自 http 响应的内容,否则,Deserialize
步骤应该可以正常工作。
我复制了你的代码并制作了一个小块来证明它。
// Define somewhere
public class GenericHttpClient
public List<T> GetJsonAsync<T>()
var content = "[\"TestProp\": \"This is some test\"]";
return JsonSerializer.Deserialize<List<T>>(content, new JsonSerializerOptions() PropertyNameCaseInsensitive=true);
public class Test
public string TestProp get; set;
// Test it
var test = new GenericHttpClient();
var result = test.GetJsonAsync<Test>();
【讨论】:
谢谢 Gordon,你说得对,但我这里没有特定的类,选择的类来自 HTML 选择,我的意思是用户必须选择类,然后我必须获取数据 【参考方案3】:就像@Mayur Ekbote 提到的那样,“由于安全原因,System.Text.Json 不支持 Type 类。”我会添加一个解决方案,但我认为这个解决方案效率不高。
将Type
更改为Dynamic
:
[Inject]
private IGenericHttpClient<dynamic> HttpClient get; set;
使用JsonElement
获取字符串形式的值:
private async Task OnPropertChange(ChangeEventArgs args)
var langCode = CultureInfo.CurrentCulture.Name;
PropertyValueList.Clear();
var list = await HttpClient.GetJsonAsync($"/api/SelectedType.Name/all");
List<object> listValue = new List<object>();
SelectedProperty = args.Value.ToString();
string fieldName = char.ToLower(SelectedProperty[0]) + SelectedProperty.Substring(1);
foreach (var item in list)
//Convert object to JsonElement
var val = ((JsonElement)item).GetProperty(fieldName).GetString();
PropertyValueList.Add(val);
为什么没有效率?
因为我得到了一个值列表 String
而不是所选类的列表。
【讨论】:
以上是关于System.Text.Json JsonSerializer:不支持“System.Type”实例的序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章
System.Text.Json.JsonSerializer.Serialize 返回空 Json 对象“”[重复]
如何在反序列化之前使用 System.Text.Json 验证 JSON
使用 System.Text.Json 修改 JSON 文件
从 Newtonsoft.Json 迁移到 System.Text.Json