Вход был недействителен.NET Core Web API

Я столкнулся со странной проблемой и почти провел 4 часа без везения.

У меня есть простой веб-API, который я вызываю в форме submit.

API-

// POST: api/Tool
[HttpPost]
public void Post([FromBody] Object value)
{
    _toolService.CreateToolDetail(Convert.ToString(value));
}

HTML-

<!DOCTYPE html>
<html>
<body>

<h2>HTML Forms</h2>
<form name="value" action="https://localhost:44352/api/tool" method="post">
  First name:<br>
  <input type="text" id="PropertyA" name="PropertyA" value="Some value A">
  <br>
  Last name:<br>
  <input type="text" id="PropertyB" name="PropertyB" value="Some value B">
  <br><br>
  <!--<input type="file" id="Files" name="Files" multiple="multiple"/>-->
  <br><br>
  <input type="submit" value="Submit">

  </form>
</body>
</html>

Когда я нажимаю кнопку отправки, я становлюсь ниже error-

{"":["The input was not valid."]}

Конфигурации в Startup class-

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddSingleton<IConfiguration>(Configuration);
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseMvc();
}

Это происходит только для запроса POST. Запрос GET работает нормально. Такая же проблема при тестировании в клиенте Postman REST. Любая помощь, пожалуйста? Пожалуйста, дайте мне знать, если я могу предоставить более подробную информацию.

Ответ 1

Не используйте FromBody. Вы отправляете как x-www-form-urlencoded (то есть стандартный пост в формате HTML). FromBody предназначен для JSON/XML.

Вы не можете обрабатывать как стандартные отправки формы, так и тела запросов JSON/XML из одного действия. Если вам нужно запросить действие в обоих направлениях, вам понадобятся две отдельные конечные точки, одна с параметром, украшенным FromBody а другая без. Другого пути нет. Фактическая функциональность вашего действия может быть преобразована в частный метод, который могут использовать оба действия, чтобы уменьшить дублирование кода.

Ответ 2

Я просто справился с подобной ситуацией; Я смог использовать [FromBody] без каких-либо проблем:

public class MyController : Controller
{
   [HttpPost]
   public async Task<IActionResult> SomeEndpoint([FromBody]Payload inPayload)
   {
   ...
   }
}

public class Payload
{
   public string SomeString { get; set; }
   public int SomeInt { get; set; }
}

Задача, которую я понял, состояла в том, чтобы убедиться, что запросы были сделаны с заголовком Content-Type, установленным как "application/json". Используя Postman, мой первоначальный запрос был возвращен как "Ввод недействителен". Добавление заголовка Content-Type исправило проблему для меня.

Ответ 3

Просто измените [FromBody] на [FromForm].
FromForm предназначен для входящих данных из отправленной формы, отправленной типом контента application/x-www-url-formencoded тогда как FromBody будет анализировать модель по умолчанию, который в большинстве случаев отправляется типом контента application/json, из тела запроса.
Благодаря fooobar.com/questions/15724449/...

Ответ 4

Как и mjwills и DavidG, вы должны, вероятно, использовать конкретный класс в реализации вашего контроллера, например:

public class MyClass
{
    public string PropertyA { get; set; }

    public string PropertyB { get; set; }
}

Ответ 5

Если вы проверите вкладку сети в своем браузере, вы заметите, что ваша форма отправляет входные значения в качестве параметров на ваш URL-адрес, а не отправляет себя. Таким образом, присвоение ему значения не отправит на ваш сервер свойство "значение".

Вместо этого метод post ожидает свойство, называемое значением, которое может быть любого типа (поскольку оно является Object), и этот параметр никогда не выполняется, поскольку он принимает эти другие параметры: PropertyA, PropertyB и Files.

Вероятно, ваш полный URL-адрес должен выглядеть следующим образом:

https://локальный: 44352/API/инструмент PropertyA = X & PropertyB = Y & Files = Z

Также обратите внимание, что вы не указали URL-адрес метода Post, поэтому я не уверен, как клиент достигнет /api/Tool. Вероятно, вам нужно указать этот url на вашем контроллере, добавив атрибут Route:

[Маршрут ( "апи/инструмент")]

Естественным путем, в противном случае является Hostname/Controller/Method или https://localhost: 44352/api/post, если ваш контроллер называется Api. В противном случае он заменит имя "api" на имя контроллера.

Ответ 7

Измените тип основного текста на требуемый формат, например, с текста на JSON (приложение).

Ответ 8

у меня та же проблема, мое решение было отключить де атрибут ApiController, я не знаю, почему вы могли прочитать это [https://docs.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-2.2#multipartform-data-request-inference] я не понимаю, в чем проблема

[Produces("application/json")]
    [Route("api/[controller]")]
    //[ApiController]<<remove this
    public class PagosController : ControllerBase

и вы метод

[HttpPost("UploadDescuento")]
public async Task<IActionResult> UploadDescuento(IEnumerable<IFormFile> files)