调用ASP.NET Core Web API时“ 400 /输入无效”

时间:2018-08-07 15:49:24

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

我正在使用邮递员测试我的Web API,并在邮递员中返回“ 400错误请求”或“输入无效”。我动作第一行的断点没有被击中。我怎么知道幕后发生了什么?

我将显示Postman的屏幕截图,但无法上传图片。这只是一个POST,其中为Body指定了多个字段。这是网址:

http://localhost:52126/api/v1/itinerary

这是动作:

[HttpPost]
[Route("api/v1/itinerary")]
public async Task<ActionResult> AddItineraryAsync([FromBody] Itinerary itinerary)
{
    if (!ModelState.IsValid) // Break point on this line not getting hit!
    {
        return BadRequest(ModelState);
    }

    await Logic.AddItineraryAsync(itinerary);

    return Ok();
}

最初,我没有为此操作指定[FromBody]。无论哪种方式都行不通。我可以检查出什么情况?

澄清(回应克里斯·普拉特):

我正处于编写第一个移动应用程序的初期阶段,作为一个自下而上的家伙,我首先开始使用一些Web API调用。我假设我会将JSON从移动应用程序传递到此服务器层。

在此Web API项目中,我没有做任何与防伪令牌有关的事情,因此我认为这些令牌没有作用……除非那是邮递员提供的。

从操作中删除参数确实可以使执行陷入我的断点,因此错误似乎与ASP.NET绑定有关。

深入研究Postman后,我确实看到标题为Content-Type指定了x-www-form-urlencoded。根据您的建议,我将其更改为application/json。但是,这似乎没有什么不同。

更多信息:

尝试了下面卡尔的建议后,我获得了更多信息。执行权落到了行动中,我看看邮递员正在传递什么。在这里:

----------------------------179455694862693501539465
Content-Disposition: form-data; name="StartPoint"

Tacoma
----------------------------179455694862693501539465
Content-Disposition: form-data; name="EndPoint"

Portland
----------------------------179455694862693501539465
Content-Disposition: form-data; name="TravelDate"

2018-8-21 07:00:00 AM
----------------------------179455694862693501539465
Content-Disposition: form-data; name="Name"

Test Itinerary
----------------------------179455694862693501539465
Content-Disposition: form-data; name="UserAccountId"

2
----------------------------179455694862693501539465
Content-Disposition: form-data; name="Comment"

Just doin' some testing.
----------------------------179455694862693501539465--

Json反序列化失败:

JsonReaderException: Input string &#x27;----------------------------179455694862693501539465&#x27; is not a valid number.

这些数字是什么,它们来自哪里?

3 个答案:

答案 0 :(得分:3)

ModelState仅在能够成功反序列化后正文/绑定的情况下才被验证。

您的问题不明确,但听起来好像您是以x-www-form-urlencoded的身份发帖。如果是这种情况,您应该[FromBody]。但是,请记住,这是一种“或/或”情况,因此,如果最终要通过JSON发布,则应保留该属性,然后从Postman发布JSON。

除此之外,请确保您未在​​使用防伪令牌验证,或者正在与请求一起发布有效令牌。防伪验证失败会缩短请求并立即返回400。

如果要发布JSON,请确保您的JSON有效。如果JSON无效,您将立即获得400。

答案 1 :(得分:1)

我尝试过像您的[FromBody] Itinerary itinerary一样,但是得到了解决。 2.1框架具有问题https://github.com/aspnet/Mvc/issues/7609https://github.com/aspnet/Mvc/issues/7799。我在2.1中工作:客户端JavaScript保持不变:

var payload = JSON.stringify({ "name": document.getElementById('firstname').value, "email": document.getElementById('email').value, "captcha": grecaptcha.getResponse() });
var oReq = new XMLHttpRequest();
oReq.ContentType = "application/json";

oReq.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {

        document.getElementById("update").innerHTML = this.responseText;
    }
    else document.getElementById("update").innerHTML = "not 4&200! : " + this.responseText;
};

oReq.open('POST', 'api/u');
oReq.send(payload);

并且控制器具有:

[Route("api/[controller]")]
//  [ApiController] // works either way
public class UController : ControllerBase
{
    [HttpPost]
    public async Task<string> signUp()
    {
        String body;
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {
            body = await reader.ReadToEndAsync();
        }

        UserSignup user = JsonConvert.DeserializeObject<UserSignup>(body);

        return user.email;
    }
}

即将上https://github.com/Hover-Us/

答案 2 :(得分:0)

评论解决方案:

对于179455694862693501539465,看来您正在使用PostMan,并将application / x-www-form-urlencode编码为Content-Type。
我建议您按照以下步骤操作:
1.使用AddItineraryAsync([FromBody] Itinerary itinerary)保留您的api;
2.在邮递员中清除标题
3.“正文”选项卡使用JSON(application / json)选择raw
4.输入有效的json字符串或仅使用{}
5.确保没有其他标头,除了application / json作为标头标签中的Content-Type。
6.发送请求以检查是否会命中api方法。