Как получить включенные имена свойств в запросе JSON web api с ядром asp. net? - PullRequest
0 голосов
/ 28 марта 2020

Я создаю asp. net core web api, и мне нужно отслеживать свойства, которые фактически были включены в тело JSON, так как. NET не имеет понятия undefined, как в javascript, просто ноль.

Я создал интерфейс, который реализован во всех моих моделях, и представляет собой просто строковый массив с именем IncludedProperties:

string[] IncludedProperties {get; set;}

У меня могут быть модели, имеющие больше этих моделей вложенный внутрь Каждый раз, когда я десериализирую одну из этих моделей, я хочу, чтобы она заполнила этот список IncludedProperties.

Например, в моем контроллере:

public async Task<ActionResult> PatchModel([FromRoute]Guid id, [FromBody] RootModel model) { ... }

И классы определены как:

public class RootModel : IIncludedProperties
{
    public string Name { get; set;}
    public string Description {get; set;}
    public NestedModel SubEntity { get; set;}
    public string[] IncludedProperties {get; set;}
}

public class NestedModel : IIncludedProperties
{
   public string Name {get; set;}
   public decimal Value {get; set;}
   public string[] IncludedProperties {get; set;}
}

Если тело JSON выглядит следующим образом:

{
    "Name": "New Entity 01",
    "SubEntity": {
        "Name": "Child Entity 01",
        "Value": 0.5
    }
}

Включенные свойства для root будут [ "Name", "SubEntity"], а включенные свойства для вложенной модели: [ "Name", "Value" ].

Я просматриваю документацию Microsoft по пользовательским конвертерам для JSON, но, похоже, мне нужно будет переписать весь конвертер json, чтобы добавить его в немного дополнительной функциональности. Есть ли способ, которым я мог бы «подключить» к существующему конвертеру, только чтобы захватить включенные имена свойств?

1 Ответ

0 голосов
/ 28 марта 2020

Это можно решить с помощью рефлексии и рекурсии. Если вы не возражаете добавить еще одну строку внутри каждого контроллера, вы можете вызвать эту функцию после привязки модели:

void PopulateIncludedProperties(IIncludedProperties obj)
{
    var properties = obj.GetType().GetProperties().ToList();
    obj.IncludedProperties = properties
        .Where(p => p.Name != "IncludedProperties" && p.GetValue(obj) != null)
        .Select(p => p.Name).ToArray();

    foreach (var prop in properties)
    {
        var value = prop.GetValue(obj);
        if (value is IIncludedProperties includedPropValue)
        {
            PopulateIncludedProperties(includedPropValue);
        }
    }
}

Пожалуйста, настройте себя, если хотите заполнить IncludedProperties из IEnumerable<IIncludedProperties>

...