.Net Core API Controller принимает данные формы или тела - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть действие API, и я хочу, чтобы оно принимало либо данные формы, либо необработанный JSON.

Вот моя функция

    [HttpPost]
    public async Task<IActionResult> ExternalLogin([FromForm]ExternalLoginModel formModel, [FromBody]ExternalLoginModel bodyModel)
    {

Поэтому я хочу, чтобы они могли отправлятьодни и те же данные двумя разными способами, при попытке этого метода с данными формы я получаю ошибку 415.Когда я пробую это с необработанным JSON, оно отлично работает.

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

1 Ответ

0 голосов
/ 27 февраля 2019

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

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

Сам форматтер прост:

/// <summary>
/// This input formatter bypasses the <see cref="BodyModelBinder"/> by returning a null result, when the request has a form content type.
/// When registered, both <see cref="FromBodyAttribute"/> and <see cref="FromFormAttribute"/> can be used in the same method.
/// </summary>
public class BypassFormDataInputFormatter : IInputFormatter
{
    public bool CanRead(InputFormatterContext context)
    {
        return context.HttpContext.Request.HasFormContentType;
    }

    public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
    {
        return InputFormatterResult.SuccessAsync(null);
    }
}

В вашем классе запуска форматировщик долженбыть добавлено:

services.AddMvc(options =>
{
    options.InputFormatters.Add(new BypassFormDataInputFormatter());
});

В вашем действии вам все равно нужно будет проверить, какой из двух параметров фактически был заполнен:

[HttpPost]    
public async Task<IActionResult> ExternalLogin([FromForm] ExternalLoginModel formModel, [FromBody] ExternalLoginModel bodyModel)
{
    ExternalLoginModel model;

    // need to check if it is actually a form content type, as formModel may be bound to an empty instance
    if (Request.HasFormContentType && formModel != null)
    {
        model = formModel;
    }
    else if (bodyModel != null)
    {
        model = bodyModel;
    }

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