输入的无效.Net Core Web API

时间:2018-07-06 13:36:03

标签: c# asp.net-core-2.0 asp.net-core-webapi

我面临一个奇怪的问题,几乎花了4个小时没有运气。

我有一个简单的Web API,可以在表单提交时调用。

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>

当我点击“提交”按钮时,我得到以下错误-

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

启动类中的配置-

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客户端中进行测试时,存在相同的问题。有什么帮助吗?如果可以提供更多详细信息,请告诉我。

8 个答案:

答案 0 :(得分:25)

请勿使用FromBody。您以x-www-form-urlencoded的身份提交(即标准HTML表单发布)。 FromBody属性用于JSON / XML。

您无法通过同一操作处理标准表单提交 JSON / XML请求正文。如果您需要两种方式都请求操作,则需要两个单独的端点,一个端点的参数用FromBody装饰,另一个端点不带。没有别的办法了。您可以将操作的实际功能分解为两个操作都可以使用的私有方法,以减少代码重复。

答案 1 :(得分:10)

我只是在这里经历了类似的情况。我可以毫无问题地使用[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标头可以解决我的问题。

答案 2 :(得分:4)

只需将[FromBody]更改为[FromForm]
FromForm属性用于由内容类型application/x-www-url-formencoded发送的已提交表单中的传入数据,而FromBody将解析模型的默认方式,在大多数情况下,该方式由内容类型发送application/json,来自请求正文。
感谢https://stackoverflow.com/a/50454145/5541434

答案 3 :(得分:0)

就像mjwills和DavidG所说的那样,您可能应该在控制器参数实现中使用一个具体的类,例如:

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

    public string PropertyB { get; set; }
}

答案 4 :(得分:0)

如果您在浏览器上检查“网络”选项卡,您会注意到表单正在将输入值作为参数发送到url,而不是发送本身。因此,将其命名为 value 不会将名为“ value”的属性发送到您的服务器。

相反,post方法期望一个名为 value 的属性,该属性可以是任何类型(因为它是一个Object),并且该参数永远不会实现,因为它正在接收其他参数:PropertyA,PropertyB和文件。

您的完整帖子网址现在应该看起来像这样:

  

https://localhost:44352/api/tool?PropertyA=X&PropertyB=Y&Files=Z

还请注意,您没有为您的 Post 方法指定网址,因此我不确定客户端如何到达 / api / Tool 。您可能需要在控制器上指定该url,并添加 Route 属性:

  

[Route(“ api / tool”)]

如果您的控制器名为Api,则自然路由为Hostname / Controller / Method或https://localhost:44352/api/post。否则,它将用控制器名称替换“ api”。

答案 5 :(得分:0)

将正文文本类型更改为所需的格式,例如从文本更改为JSON(应用程序)。

答案 6 :(得分:0)

我遇到了同样的问题,我的解决方案是禁用depi属性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)

答案 7 :(得分:0)

JavaScript和DotNet Core Web API实现。希望这对外面的人有帮助。

    //JavaScript

    var dataList = [];
    var dataObject = {};

    dataObject["field1"] = "field1";
    dataObject["field2"] = "field2";

    dataList.push(dataObject);

    $.ajax("https://localhost:1111/api/Sample",
    {
        type: "POST",
        async: false,
        contentType: "application/json",
        dataType: 'json',
        data: JSON.stringify(dataList),
        success: function (responseObject) {
            console.log(responseObject);
        }
    });

    //DOT NET CORE WEB API
    //Sample Request Model
    public class RequestObject{
        public string field1 { get; set; }
        public string field2 { get; set; }
    }
    
    [Route("api/[controller]")]
    [ApiController]
    public class SampleController : ControllerBase
    {
          //Sample POST API
          [HttpPost]
          public string Post([FromBody] List<RequestObject> requestObjectList)
          {
               var youWelcome = requestObjectList;
               return "JavaScript Post Successful.";
          }
    }