Модель привязки вложенных свойств в ядре asp.net 2.2 - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь создать общий сложный объект для моих моделей (параметры действия) и использовать его во многих местах.

Вот пример кода:

[HttpGet("/api/values")]
public ActionResult<string> Get([FromQuery] MyModel model) {
    var sb = new StringBuilder();
    sb.AppendLine(model.Id);
    sb.AppendLine($"{model.Id}-{model.Generated?.DateStart}-{model.Generated?.DateEnd}");
    sb.AppendLine($"{model.Id}-{model.Reference?.DateStart}-{model.Reference?.DateEnd}");
    return sb.ToString();
}


public class MyModel {
    public string Id { get; set; }
    public DateInfo Generated { get; set; } = new DateInfo();
    public DateInfo Reference { get; set; } = new DateInfo();
}

public class DateInfo {
    public DateTime? DateStart { get; set; }
    public DateTime? DateEnd { get; set; }
    public RelativeTime? RelativeTime { get; set; }
}

Представьте, что класс DateInfo будет иметь валидацию и общие свойства, которые будут использоваться во многих моделях.

Добавление [FromQuery(Name = "Something")] к вложенным свойствам делает хитрость, но не позволяет иметь два вложенных свойства одного типа.

UDPATE:

Я понимаю, что добавление полностью определенного имени свойства ( ... / values? Id = 1 & Generated.DateInfo = 2 & Reference.DateInfo = 3 ) заставит его работать, но это будет очень уродливый способ вызывать любой API. Дефисы - это путь, а не точки.

Я хотел бы отобразить привязку так же, как и для сопоставления обычного свойства.

Как этого добиться?

1 Ответ

0 голосов
/ 07 ноября 2018

вижу два варианта.

Вариант 1: Просто создайте новый, плоский класс {Id, Foo, Bar} для использования в качестве параметра вашего метода действия. Затем вы можете сопоставить это с MyModel. Такой подход я бы рекомендовал как наиболее поддерживаемый.

Вариант 2: Пользовательская привязка модели, как указано ниже:

[ModelBinder(BinderType = typeof(MyModelBinder))]
public class MyModel 
{
    public string Id { get; set; }
    [FromQuery]
    public Info ComplexNestedProperty { get; set; }
}

public class AuthorEntityBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var model = new MyModel 
        {
            Id = bindingContext.ValueProvider.GetValue("id"),
            ComplexNestedProperty = new Info 
            {
                Foo = bindingContext.ValueProvider.GetValue("foo"),
                Bar = bindingContext.ValueProvider.GetValue("bar")
            }
        };            

        bindingContext.Result = ModelBindingResult.Success(model);
        return Task.CompletedTask;
    }
} 

В качестве дополнения к Вариант 2 вы могли бы разумно написать какое-нибудь отражение, которое получит все имена конечных свойств вашей вложенной модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...