#c# #asp.net-core
#c# #asp.net-ядро
Вопрос:
Я создал несколько классов для моделирования данных JSON, возвращаемых из API. Раздел с релевантностью выглядит следующим образом:
public class ErrorClass
{
public string status { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? unknown_properties { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? invalid_coordinates { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? location_error { get; set; }
}
Некоторые из этих свойств ошибки будут отображаться только тогда, когда в моделируемом JSON присутствует ошибка (нулевые значения игнорируются). Я хочу настроить помощника для обработки ошибок. Это проверит, были ли заполнены определенные значения в объекте, и добавит их в сообщения об ошибках соответственно. У меня есть список имен свойств, потенциально принадлежащих объекту класса. Я хочу перебрать список строк и проверить, имеют ли они значение в текущем объекте. Моя проблема в том, что я не уверен, как сделать что-то вроде:
public class ErrorsHelper
{
string[] badRequestErrors = {"invalid_coordinates", "location_error"};
public void Process_Errors(dynamic errors)
{
for (int i = 0; i < badRequestErrors.Length; i )
{
var badRequestError = badRequestErrors[i];
if (errors.badRequestError[i])
{
// Add to list, etc.
}
}
}
}
Потому что компилятор ищет свойство имени переменной вместо значения этой переменной. Как я могу искать имя свойства в объекте C # таким образом?
Заранее благодарю вас!
Комментарии:
1. Я бы использовал
JObject
вместо десериализации в класс.
Ответ №1:
Используя отражение, это вернет все свойства JsonPropertyAttribute
, аннотированные с.
var properties = typeof(ErrorClass)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.GetCustomAttribute<JsonPropertyAttribute>() != null)
.ToList();
Вы можете получить доступ к их именам следующим образом:
foreach (var propertyInfo in properties)
{
Console.WriteLine(propertyInfo.Name);
}
Вы можете получить их значение с помощью:
var propertyValue = propertyInfo.GetValue(obj);
Комментарии:
1. Я пробовал такой подход. Проблема, с которой я столкнулся, заключается в том, что класс, который входит в
typeof()
, может меняться. Я должен был упомянуть об этом. Он используется для множества разных конечных точек, у которых разные классы ошибок.2. Затем вы должны использовать
.GetType()
илиtypeof(T)
, если у вас есть универсальный метод.3. Проблема в том, что если я попытаюсь использовать
.GetType()
, а затем передать эту переменную вtypeof()
, я получу сообщение об ошибке:errorType' is a variable but is used like a type
4.
.GetType()
дает вам тип. Затем вы можете вызвать.GetProperties
его.
Ответ №2:
Высокоуровневый ответ заключается в том, что вы бы использовали reflection
. смотрите: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection
Рефлексия часто не рекомендуется, но это правильный подход. См.:
Для некоторого обсуждения. Пара моментов: обычно он «медленнее» (хотя часто не практически) и может обходить проверки компилятора (возможно, приводящие к ошибкам).
Если какая-либо из ваших ошибок достаточно «плохая», чтобы остановить весь процесс, вы также можете yield return
использовать средство проверки ошибок и просто проверить все различные типы ошибок в serial, при условии, что типов ошибок не слишком много.
Ответ №3:
Вы можете получить свойства класса, используя приведенный ниже код:
PropertyInfo[] propertyInfos = typeof(ErrorClass).GetProperties();
Array.ForEach(propertyInfos, property =>
Console.WriteLine("Property Name is :" property.Name));
Ответ №4:
Я так и не нашел решения этой проблемы. Проблема заключалась в том, что .getType()
возвращалось только class type
object
значение, и поэтому выполнение предоставленных решений на нем давало бы только available
свойства, а не те, которые на самом деле были ненулевыми в объекте.