ASP.NET RAZOR: Multiple page methods for POST / GET & Ajax call - possible issues
In my current project I need a additional page method for POST requests beside the default page POST method. Actually I don't use any page POST methods because I use in the most of the times the WebAPI REST endpoints for all CRUD operations. But for the new requirement I need a POST method to send out an E-Mail message from a clientside call. For the client call I used jQuery and implemented the following code:
$.ajax({
url: "/WebForm/FormData/SendMessage",
type: "POST",
contentType: "application/json; charset=utf-8",
data: options.data,
success: function (d) {...},
error: function (d) { ...}
});
Page url: /WebForm/FormData
In the page model class I added a new post method with the prefix "OnPost" to mark the method as POST-method:
public async Task<JsonResult> OnPostSendMessage([FromBody] CloudFormMessageReply messageToSend) { ... }
I thought everything is perfect in place and I tested my implementation but nothing happened after I executed the jQuery post request. I set a breakpoint in the new post method but the debugger never stopped there. Then I checked the network connection and noticed an error: 404 Not Found 😢
Then I tried to use explicit the Razor page feature "named handlers methods" and I changed my POST request to /WebForm/FormData/Handlers?handler=sendmessage BUT same 404 error again.
Finally I noticed that I forgot to add "{handler?}" to my page directive in the *.html.cs page. So I completed it to @page "{handler?}"
Finger cross and next try ... but now: 400 Bad Request 😒
For testing purpose I added a submit button to the page and tested the post method and the method call worked as expected. Then I checked the difference between the full post and my jQuery background post. Then I noticed that I forgot to add the RequestVerificationToken to my call.
Shame on me 🙄
Request Verification in ASP.NET Razor Pages is a mechanism designed to prevent possible Cross Site Request Forgery attacks, also referred to by the acronyms XSRF and CSRF.
Cross-site request forgery is an attack against web-hosted apps whereby a malicious web app can influence the interaction between a client browser and a web app that trusts that browser. These attacks are possible because web browsers send some types of authentication tokens automatically with every request to a website. This form of exploit is also known as a one-click attack or session riding because the attack takes advantage of the user's previously authenticated session. Cross-site request forgery is also known as XSRF or CSRF.
More details on this topic: Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core
Solution to resolve my issue was very easy. I added the token to my jQuery call (short version):
$.ajax({
url: "/WebForm/FormData/SendMessage",
type: "POST",
contentType: "application/json; charset=utf-8",
data: options.data,
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (d) {...},
error: function (d) { ...}
});
Now, before I send the request I add the necessary token to the request. And finally my post method was called from the jQuery request.
Additional post method |
Happy coding 😊
Kommentare