#c# #asp.net-core #blazor #system.text.json
Вопрос:
Я получил ошибку, связанную с безопасностью, когда попытался десериализоваться с помощью System.Text.Json JsonSerializer`.
- Чего я хочу достичь?
Я хочу предоставить пользователю возможность управлять некоторыми записями в моей базе данных, чтобы использовать этот сценарий:1 — Пользователь может выбрать модель моей библиотеки классов.
2 — После выбора класса пользователь выберет свойство(файл) из этого класса.
3 — Пользователь получит список значений выбранного свойства.
4 — Последнего шага здесь сейчас нет, пользователь может отредактировать значение сертификата.
Это мой фрагмент кода:
- Моя страница.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:
Система.Текст.Json не поддерживает класс типа по соображениям безопасности. Вы отправляете полное имя сборки в виде строки и снова пытаетесь создать тип на стороне клиента.
Комментарии:
1. Привет @Mayur, я понимаю, что
Type class
это вызывает проблему, Не могли бы вы помочь мне выполнить то, что вы сказали о «Вы отправляете полное имя сборки в виде строки и снова пытаетесь создать тип на стороне клиента».2. Не могли бы вы подробнее рассказать о своем варианте использования/ потоке?
3. Хорошо, я добавлю какое-то решение, но оно не очень эффективное, поэтому, пожалуйста, прочтите его, и если вы сможете сделать его лучше, это будет здорово!.
4. Я думаю, что мы столкнулись с проблемой 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>();
Комментарии:
1. Спасибо Гордон, вы правы, но у меня здесь нет определенного класса, выбранный класс происходит из выбора HTML, я имею в виду, что пользователь должен выбрать класс, а затем я должен получить данные
Ответ №3:
Например, то, о чем упоминал @Mayur Ekbote: «System.Text.Json не поддерживает тип класса по соображениям безопасности.» Я добавлю решение, но я не думаю, что это решение очень эффективно.
- Изменить
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
вместо списка выбранных классов.