Пользовательская привязка модели, смешивающая данные маршрута и тела - PullRequest
0 голосов
/ 17 октября 2019

У меня есть модель с 3 свойствами, которые я хочу связать и проверить с помощью ASP.NET Core. Из этих 3 свойств 2 следует связать из тела JSON POSTed, а третье - из параметров маршрута:

public class CustomModel
{
    public string Id_Model { get; set; } //Bind it from RouteData
    public string Value { get; set; } //Bind it from Body
    public string Type { get; set; } //Bind it from Body
}

[Route("[controller]")]
public CustomController : ControllerBase
{
    [HttpPost("{Id_Model}")]
    public IActionResult Post(CustomModel model)
    {
        return Ok();
    }
}

Дело в том, что я не хочу добавлять какие-либо атрибуты всама модель (она будет объявлена ​​в другой сборке, и мне не нужны зависимости от Microsoft.AspNetCore в этой сборке).

Я пытался создать CustomModelBinder, но застрял только сданные маршрута доступны из bindingContext.ValueProvider, и я не знаю, как получить данные Body / Json.

Я пытался использовать FormValueProviderFactory, и создать экземпляр с new ValueProviderFactoryContext(bindingContext.ActionContext), но в результате провайдервсегда null.

Есть идеи, как можно сделать этот тип смешанного связывания?

Ответы [ 2 ]

1 голос
/ 18 октября 2019

Я пытался создать CustomModelBinder, но я застрял только с данными маршрута, доступными из bindingContext.ValueProvider, и я не знаю, как получить данные Body / Json.

Вы можете прочитать тело запроса в пользовательском связывателе модели:

public class testDtoEntityBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            bindingContext.HttpContext.Request.EnableBuffering();
            var body = bindingContext.HttpContext.Request.Body;
            body.Position = 0;


            string raw = new System.IO.StreamReader(body).ReadToEnd();

            //now read content from request content and fill your model 
            var result = new testDto
            {
                A = "",
                B = 1,
            };


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

Используйте для вашей модели, как показано ниже:

[ModelBinder(BinderType = typeof(testDtoEntityBinder))]

Вы также можете получить данные маршрута из bindingContext.HttpContext.Request.

0 голосов
/ 17 октября 2019

Я не уверен, что вы имели в виду это:

[HttpPost("{Id_Model}")]
public IActionResult Post([FromBody] CustomModel model, string Id_Model)
{
    model.Id_Model = Id_Model;

    // rest of the code as you wish

    return Ok(model);
}

Таким образом, вы можете поймать это как вы POST следующее к этой конечной точке: http://localhost:63676/Custom/100

enter image description here

Надеюсь, это помогло.

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