Мне нужно реализовать привязку пользовательской модели, и я пытаюсь реализовать IModelBinder для приложения .Net Core 2.1 API.

Model класс -

  [ModelBinder(BinderType = typeof(PersonBinder))]
  public class Person
  {
     public name {get;set;}
     public address {get;set;}
  }

API метод -

 [HttpPost]
 [Route("process")]
 public async Task<ActionResult<int>> ProcessAsync([ModelBinder(typeof(PersonBinder))]Person person)
 {
     ...
 }

Метод привязки модели -

public Task BindModelAsync(ModelBindingContext bindingContext)
{
    var modelName = bindingContext.ModelName; //modelName is empty string
    ...
}

Запрос почтальона, который я использую для тестирования, содержит объект JSON в body, и его простейшая форма выглядит так:

{
    "name": "name1"
    "address": "address1" 
}

Обратите внимание, что этот запрос исходит от существующего унаследованного клиента, над которым у меня нет контроля, и объект JSON, который будет приходить как тело в POST, не будет иметь имени.

В QuickWatch в VisualStudio я также вижу, что bindingContext.ValueProvider.Count is 1 и bindingContext.ModelMetadata имеют Parameter из person и Type из {{X7} } и bindingContext.FieldName равно person. И на удивление bindingProvider.Result равно Failed, а bindingContext.ModelName всегда String.Empty

Кто-нибудь может помочь мне получить ModelName от BindingContext. И если в этой ситуации нет способа получить ModelName, то как я могу прочитать объект Person из BindingContext?

0
user979189 30 Мар 2019 в 17:34

1 ответ

Лучший ответ

Я выяснил, как лучше всего читать опубликованные параметры, и, поскольку я не получил ответа на этот вопрос, я опубликую, как я это сделал, если это может быть полезно для кого-то еще

        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            var request = bindingContext.HttpContext.Request;

            using (var reader = new StreamReader(request.Body, Encoding.UTF8))
            {
                var bodyString = reader.ReadToEnd();
                var person = bodyString.DeSerialize<Person>(); //this is custom logic to de-serialize to object from JSON string

                //write your model binding logic here...

                bindingContext.Result = ModelBindingResult.Success(person);
            }

            return Task.CompletedTask;
        }
1
user979189 2 Апр 2019 в 14:15