Hi @Ashkan
However, when sending by ajax, I get a 400 and bad request error and the handler is not called Please guide me where I am doing wrong ?
The issue might relate the Anti-Forgery Tokens.
You can check Anti-Forgery Tokens workflow:
To help prevent CSRF attacks, ASP.NET MVC uses anti-forgery tokens, also called request verification tokens.
- The client requests an HTML page that contains a form.
- The server includes two tokens in the response. One token is sent as a cookie. The other is placed in a hidden form field. The tokens are generated randomly so that an adversary cannot guess the values.
- When the client submits the form, it must send both tokens back to the server. The client sends the cookie token as a cookie, and it sends the form token inside the form data. (A browser client automatically does this when the user submits the form.)
- If a request does not include both tokens, the server disallows the request.
By default, it will automatic generation of antiforgery tokens for HTML form elements happens when the <form>
tag contains the method="post"
attribute and either of the following are true:
- The action attribute is empty (
action=""
). - The action attribute isn't supplied (
<form method="post">
).
Then, when we submit the data to the back-end handler method, it required to add the Verification Token in the request header (the browser will add the cookie token), if the token is invalid or missing, it will show the 400 error.
So, try to modify your code as below: add the verification token to the header and select the first upload file (based on the view model to select the first upload file).
$("#sendButton").click(function (event) {
event.preventDefault();
var userId = $("#userId").val();
var userName = $("#username").val();
var message = $("#message").val();
var groupId = $("#groupid").val();
var attachFile = $("#f").get(0).files[0]; //select the upload file.
var formData = new FormData();
formData.append("FileAttach", attachFile);
formData.append("UserId", userId);
formData.append("UserName", userName);
formData.append("Message", message);
formData.append("GroupId", groupId);
$.ajax({
type: "POST",
url: "Index?handler=SendMessage",
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }, //add the verification token to the header.
data: formData,
encyType: "multipart/form-data",
processData: false,
contentType: false
});
});
The whole sample code as below:
Index.html
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<div class="row">
<div class="col-md-4">
<form method="post">
<div class="form-group">
<label for="userId" class="control-label"></label>
<input id="userId" name="userId" class="form-control" value="11" />
</div>
<div class="form-group">
<label for="username" class="control-label"></label>
<input id="username" name="username" class="form-control" value="AA" />
</div>
<div class="form-group">
<label for="message" class="control-label"></label>
<input id="message" name="message" class="form-control" value="default" />
</div>
<div class="form-group">
<label for="groupid" class="control-label"></label>
<input id="groupid" name="groupid" class="form-control" value="groupA" />
</div>
<div class="form-group">
<label for="f" class="control-label"></label>
<input id="f" name="f" type="file" class="form-control" />
</div>
<div class="form-group">
<input type="button" value="Send" id="sendButton" class="btn btn-primary" />
</div>
</form>
</div>
</div>
@section Scripts{
<script>
$(function () {
$("#sendButton").click(function (event) {
event.preventDefault();
var userId = $("#userId").val();
var userName = $("#username").val();
var message = $("#message").val();
var groupId = $("#groupid").val();
var attachFile = $("#f").get(0).files[0]; //select the upload file.
var formData = new FormData();
formData.append("FileAttach", attachFile);
formData.append("UserId", userId);
formData.append("UserName", userName);
formData.append("Message", message);
formData.append("GroupId", groupId);
$.ajax({
type: "POST",
url: "Index?handler=SendMessage",
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }, //add the verification token to the header.
data: formData,
encyType: "multipart/form-data",
processData: false,
contentType: false
});
});
});
</script>
}
Index.html.cs
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
public IActionResult OnPostSendMessage([FromForm] InsertChatViewModel model)
{
return Page();
}
The result as below:
Or you can disable the AntiforgeryToken use the IgnoreAntiforgeryToken
attribute:
[IgnoreAntiforgeryToken(Order = 1001)]
public class IndexModel : PageModel
More detail information, see Request Verification.
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion