Токен MVC не допускает загрузку нескольких файлов при публикации через AJAX - PullRequest
0 голосов
/ 06 февраля 2019

Я знаю, что загрузка нескольких файлов работает нормально, потому что, когда я закомментирую [ValidateAntiForgeryToken], я могу выбрать несколько файлов, и они будут загружены без каких-либо проблем, как и предполагалось.

Однако, когда я ставлю [ValidateAntiForgeryToken] назад If I select 2 or more files, я получаю сервер 500 status error и ни один из файлов не загружается.

Дополнительно я добавлю ошибку: Failed to load resource: the server responded with a status of 500 (Internal Server Error) трассировка стека говорит, что она остановилась на line 1 of Upload action

Однако, если я выберу 1 файл, он будет успешно загружен, и я получу status code 200.

Я все еще новичок в этом - я не могу сказать, что не так.Я ценю любую помощь по этой загадке.: -)

Это действие моего контроллера:

[HttpPost]
[ValidateAntiForgeryToken]   // If I comment this out, everything works as intended
public ActionResult Upload()
{
    for (int i = 0; i < Request.Files.Count; i++)
    {
        var file = Request.Files[i];

        var fileName = Path.GetFileName(file.FileName);

        var path = Path.Combine(Server.MapPath("~/Some/FilePath"), fileName);
        file.SaveAs(path);
    }

    return Json(new { success = true, responseText = "Success!" }, JsonRequestBehavior.AllowGet); //This is placeholder, I'll implement validation later
}

HTML:

@Html.TextBoxFor(model => model.file, new { type = "file", id = "file-upload", multiple="multiple" })
@Html.ValidationMessageFor(model => model.file, "", new { @class = "text-danger" })

<div id="selectedFiles"></div>

Я создаю свой собственный массив файлов, чтобы можно было удалить егоособенность файла.Это мой способ вызова функции UploadAjax:

var storedFiles = [];    //this is what I pass to it.

$("#stupidTest").click(function () {
    UploadAjax(storedFiles);
});

JQuery, AJAX.Это функция загрузки.

function UploadAjax(storedFilesArray) {
    var formData = new FormData();

    for (let i = 0; i < storedFilesArray.length; i++) {
        let file = storedFilesArray[i];

        formData.append('__RequestVerificationToken', getToken()); //appends the value to the formData. 
        formData.append("file-upload", file);
    }
    $.ajax({
        type: "POST",
        dataType: 'json',
        cache: false,
        url: '/Home/Upload',
        data: formData,
        contentType: false,
        processData: false,
        success: function (response) {
            ...
        },
        error: function (response) {
            ...
        }
    });
}

**Edit: Found that this happened at the same second my multiple file upload request failed**

System.Web.Mvc.HttpAntiForgeryException: The anti-forgery token could not be
decrypted. If this application is hosted by a Web Farm or cluster, ensure that
all machines are running the same version of ASP.NET Web Pages and that the
<machineKey> configuration specifies explicit encryption and validation keys.
AutoGenerate cannot be used in a cluster.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Может быть, вам следует установить formData.append('__RequestVerificationToken', getToken()); вне цикла?

var formData = new FormData();
formData.append('__RequestVerificationToken', getToken()); //appends the value to the formData. 
for (let i = 0; i < storedFilesArray.length; i++) {
        let file = storedFilesArray[i];
         formData.append("file-upload", file);
    }
0 голосов
/ 06 февраля 2019

Извлеките эту строку из цикла (и поместите ее выше или ниже цикла):

formData.append('__RequestVerificationToken', getToken()); //appends the value to the formData.

append будет продолжать добавлять значение __RequestVerificationToken, которое передается на сервер.После того, как он был добавлен один раз (т. Е. Если вы выбрали 2 или более файлов), значение не будет действительным токеном XSRF для защиты от подделки.И тогда это не в состоянии проверить, и таким образом вы получаете ошибку на сервере.

...