UPDATE:
Some weird behaviour. If I post to a controller it works and I get files and data. However, if I post to the page itself (Razor code behind) public void OnPost(...)
I get the 400 error. It’s almost like the page can’t find itself, which is also weird because other methods on that page OnGet
and OnGetData
work with no issue.
The error that gets shown in the browser console is here
If you click the links it goes to the page so I know the path is valid.
I put everything on the page so that it’s self-contained and I can reuse the page anywhere, and I don’t have to worry about changes elsewhere breaking that page, nor changes to that page breaking anything else. The pages are data-driven, so configured via a database, I have around 7 or 8 pages (of this type) and they all work just fine, but this is the first of this type that has file upload as part of its functionality.
THE PROBLEM:
I have the following situation. This works perfectly, but when I try to use formData
to enable file upload I get a 400 (bad request) error. I have tried all manner of content-type and enctype, but nothing seems to work. Any ideas as to what’s going wrong?
You can see the commented lines. if I switch to those I always get a 400 ‘bad request’
Visual Studio 2022, Net 8.
My Form (BS5 Modal)
<form id="frmItemLocalForm" method="post" name="frmItemLocalForm" novalidate="novalidate" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<input type="hidden" name="controlId" id="controlId" value="@ViewData["controlid"]" />
<input type="hidden" name="itemId" id="itemId" value="@ViewData["itemId"]" />
<input type="hidden" asp-for="UserDocument.Created" name="Created" />
<!--Modal Header-->
<div class="modal-header">
<h4 class="modal-title">Edit User Document</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<!-- Modal body -->
<div class="modal-body">
<div class="row my-1">
<label class="col-form-label col-md-2">Name</label>
<div class="col-md-10">
<input type="text" class="form-control" placeholder="Name" asp-for="UserDocument.DocumentName" name="DocumentName" data-rule-required="true" />
</div>
</div>
<div class="row my-1">
<label class="col-form-label col-md-2">File</label>
<div class="col-md-10">
<input type="file" class="form-control fileUpload" placeholder="User Document" name="userdocumentfileupload" id="userdocumentfileupload" data-rule-required="true" required />
<br />@Model.UserDocument?.DocumentName @Model.UserDocument?.FileName
</div>
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="submit" id="editLocalForm" class="btn btn-primary">OK</button>
<button type="button" class="btn btn-danger close-button" data-bs-dismiss="modal">Close</button>
</div>
</form>
$(document).on("click", "#editLocalForm", function (e) {
e.preventDefault();
e.stopPropagation();
var myform = $("#frmItemLocalForm");
var valid = myform.valid();
if (valid) {
var formData = new FormData();
//$(".fileUpload").each(function () {
// var fileInput = $(this)[0];
// var file = fileInput.files[0];
// if (file.size > 0) {
// formData.append($(this).attr("id"), file);
// }
//});
//formData.append("myFormData", myform.serialize());
$.ajax({
url: formUrl,
data: myform.serialize(),//formData,
dataType: "html",
contentType: "application/x-www-form-urlencoded",
processData: false,
method: "post",
success: function (result) {
$(".close-button").click();
table.ajax.reload(null, false);
},
error: function (err) {
console.log(err);
}
});
}
});
Server End Point.
I have a break point here that doesn’t even get hit
public void OnPost()
{
... Request.Form.Files...
}
2
Answers
Have you tried change
contentType: "application/x-www-form-urlencoded"
tocontentType: 'multipart/form-data'
or maybecontentType: false
?With those contentType, you can send
myform
without serializing it inside thedata
of your ajaxRazor Pages enable anti-forgery token validation by default, so you need add this token to header in ajax. Otherwise you may receive 400 Bad Request error.
If you use ajax post the data with file input, it should be:
Also you need use FormData instead of
form.serialize()
.A whole working demo:
Index.cshtml
Index.cshtml.cs