400 Bad Request when POST-ing to Razor Page

倾然丶 夕夏残阳落幕 提交于 2020-06-10 02:59:27

问题


My page has...

@page "{candidateId:int}"

... and

@Html.AntiForgeryToken()

Model has...

public void OnGet(int candidateId)
{

}

public void OnPost(int candidateId)
{

}

GET works fine. Here is my AJAX request..

$.ajax({
    type: "POST",
    url: "/Skills/" + candidateId,
    beforeSend: function (xhr) {

        xhr.setRequestHeader("XSRF-TOKEN",
            $('input:hidden[name="__RequestVerificationToken"]').val());
    },
    data: {

        name: 'hi mum'
    },

    success: function (response) {
    },
    failure: function (response) {

        alert(response);
    }
});

Browser receives useless error message... 400 Bad Request.

What am I missing?


回答1:


You are getting a 400 (Bad Request) response because the framework expects the RequestVerificationToken as part of the posted request.The framework uses this to prevent possible CSRF attacks. If your request does not have this information, the framework will return the 400 bad request. Your current code is not sending it.

Change the code to this

headers:
{
    "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},

This will add a new item with key RequestVerificationToken to the request header and the framework should not throw a 400 response when the call is made. (assuming your view code generated the hidden input for the __RequestVerificationToken hidden input)

You can make the code more robust by injecting the IAntiforgery implementation to the view/page and using the GetAndStoreTokens method.

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
    return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}

and call this GetAntiXsrfRequestToken function to get the value in your javascript

headers:
{
    "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},

You also probably want to use the PageModel's CandidateId property to create the url. Something like this

url: "/Skills/@Model.CandidateId",

Also, you do need to call @Html.AntiForgeryToken() method explicitly to generate the token input. Having a form with post method with no action attribute value will generate the hidden input for you.

<form method="post">
   <!-- your inputs-->
</form>


来源:https://stackoverflow.com/questions/48373229/400-bad-request-when-post-ing-to-razor-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!