I'm trying to upload file(s) with an ajax call and validate the anti forgery token. I've had a look around and built a method to validate the anti forgery token on the controller. However whenever I have @Html.AntiForgeryToken
on the view, my files do not get populated. Even though it validates the anti forgery token. It doesn't seem to be getting sent with the request but I'm unsure why.
ajaxSendOverride:
$(document).ready(function () {
var securityToken = $('[name=__RequestVerificationToken]').val();
$(document).ajaxSend(function (event, request, opt) {
if (opt.hasContent && securityToken) { // handle all verbs with content
var tokenParam = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
opt.data = opt.data ? [opt.data, tokenParam].join("&") : tokenParam;
// ensure Content-Type header is present!
if (opt.contentType !== false || typeof event.contentType !== 'undefined') {
request.setRequestHeader("Content-Type", opt.contentType);
}
}
});
});
Ajax:
$(document).on("submit", "[data-upload-contract-form]", function (e) {
e.preventDefault();
var formData = new FormData($('[data-upload-contract-form]')[0]);
if ($('[data-upload-file]').val() != "") {
$.ajax({
url: $(this).attr('action'),
data: formData,
type: 'POST',
processData: false,
contentType: false,
headers: {
'__RequestVerificationToken': $('[name=__RequestVerificationToken]').val()
},
success: function (data) {
if (data.Success === true) {
$('[data-contract-error-message]').text();
ReturnDataTableForUploadFile($('[data-upload-file-supplier-contract-id]').val());
table.ajax.reload();
}
else {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text(data.ResponseText);
}
}
})
.fail(function () {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text("Something went wrong uploading your file, please try again.");
});
}
else {
$('[data-contract-error-message]').show();
$('[data-contract-error-message]').text("No contract to upload");
}
});
Validation:
public sealed class AuthorizeAntiForgeryToken : System.Web.Mvc.FilterAttribute, System.Web.Mvc.IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookie != null ? cookie.Value : null,
httpContext.Request.Headers["__RequestVerificationToken"]);
}
}
Controller:
public async Task<JsonResult> UploadContract(UploadContract model)
{
if (ModelState.IsValid)
{
try
{
foreach (var item in model.Contracts)
{
string filePath = WebConfigurationManager.AppSettings["SupplierContractPath"] + GetSelectedClientId() + "\\" + item.FileName;
_supplierFileManager.UploadFile(item, filePath);
await _supplierFileManager.SaveContractToDatabase(model.SupplierContractID, item.FileName);
}
return Json(new { Success = true });
}
catch (Exception e)
{
return Json(new { Success = false, ResponseText = e.Message });
}
}
else
{
string errorMessage = "";
foreach (var item in ModelState.Values.SelectMany(r => r.Errors))
{
errorMessage += "<p>" + item.ErrorMessage + "</p>";
}
return Json(new { Success = false, ResponseText = errorMessage });
}
}
How can I send my files with the anti forgery token?