将表单数据发布到MVC Core API

Kev*_*fer 10 c# rest asp.net-core-mvc asp.net-core

我想使用AJAX将数据发布到我的API,但我遇到了问题.我正在使用Fiddler测试我的API并且我能够正确发布JSON但是当发布名称/值urlencoded字符串时,我得到400 Bad Request,响应正文为'{"":["输入无效."]}".

我的调试窗口显示: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor:Information: Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.SerializableError'.

发布的JSON是:

{
    "Name": "Test"
}
Run Code Online (Sandbox Code Playgroud)

发布的表单数据是:

Name=Test
Run Code Online (Sandbox Code Playgroud)

这是控制器和动作:

[Route("api/[Controller]")]
[ApiController]
public class AccountsController : Controller
{
    [HttpPost]
    public IActionResult CreateAccount(Account account)
    {
        //code
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Account类:

public class Account
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
    public string Website { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

很明显,在模型绑定期间存在问题,但表单数据似乎有效(我还使用AJAX生成表单数据并获得400).

Kir*_*kin 18

Andrew Lock 在他的帖子模型中绑定了2016 年的ASP.NET Core中的JSON POST,他解释说,为了在ASP.NET Core中绑定JSON POST,[FromBody]必须在参数上指定属性,如下所示:

[HttpPost]
public IActionResult CreateAccount([FromBody] Account account)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

随着ASP.NET Core 2.1的推出[ApiController],不再需要这样做了.这里重要的是,[FromBody]当绑定的类型是"复杂的"(在您的示例中)时,此属性有效地推断出属性的存在.换句话说,就好像你已经编写了我上面演示的代码一样.

在他的帖子中,安德鲁还说明了以下内容:

在某些情况下,您可能需要能够将两种类型的数据绑定到操作.在这种情况下,你有点卡住,因为不可能让相同的终点接收两组不同的数据.

在这里,当提到两种类型的数据时,Andrew指的是JSON帖子和基于表单的POST.他继续解释如何实际达到要求的结果.为了您的目的修改他的示例,您需要执行以下操作:

// Form.
[HttpPost("FromForm")]
public IActionResult CreateAccountFromForm([FromForm] Account account)) =>
    DoSomething(account);

// JSON.
[HttpPost("FromBody")]
public IActionResult CreateAccountFromBody(Account account) =>
    DoSomething(account);

private IActionResult DoSomething(Account account) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在安德鲁的例子中,它[FromBody]是显式的并且[FromForm]是隐式的,但是考虑到对[ApiController]默认值的影响,上面的修改示例翻转了它.