MVC 5 Ajax文件上传在控制器中没有反序列化

本文关键字:控制器 反序列化 Ajax 文件 MVC | 更新日期: 2023-09-27 17:50:46

出于某种原因,我在使用multipart/form-data类型反序列化发送的数据时遇到了问题。这是一个MVC 5项目,数据没有映射到控制器方法中。奇怪的部分是,在小提琴手所有的数据似乎有效没有问题。然而,在调试时,我可以清楚地看到参数都是空的。

这是一个向控制器发送一个文本字段(隐藏)和最多两个文件的表单。签名如下:

[HttpPost]
public async Task<ActionResult> UploadFile(string id, FormCollection form, IEnumerable<HttpPostedFileBase> files)

我认为方法的实现与这个问题无关,因为问题是参数没有被填充。

在不发布实际文件内容的情况下,这里是Fiddler输出的编辑版本:

POST http://localhost:52876/Projects/UploadFile/5550cdc52300560f6c7b36eb HTTP/1.1
Host: localhost:52876
Connection: keep-alive
Content-Length: 90889
Authorization: Negotiate oXcwdaADCgEBoloEWE5UTE1TU1AAAwAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAABXCiOIGAbEdAAAADwAbnJriMKEzkS3OifgoahejEgQQAQAAAPUXp1AtIpqEAAAAAA==
Accept: */*
Origin: http://localhost:52876
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36
Content-Type: multipart/form-data
DNT: 1
Referer: http://localhost:52876/Projects/ProjectSetupForm/5550cdc52300560f6c7b36eb
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: donotshowgettingstarted=%7B%22state%22%3Atrue%7D; __RequestVerificationToken=UnL5s7w5OYKgywE5L8jqwbH8PulgF0BG0Ne_qZV5QMOj7pWdXw6qzN1pRYqc4rwKYiWveltrBs1SmJe2o7ndXufkOJFrC1wHOoK2zAXdnQw1
------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="__RequestVerificationToken"
  f25ipWgwweX4S9Y6aEnQdxGCsvr7D3RznTui8_b5paCT1uTV8UNG0d6zJDXKUWYPHISOKmgD24KH206x_PGQ3KpXlG9YgOL-qqJ8v7DPETVfGk2PvsFm2aKuAS3xAYZI0
------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="files"; filename="MyIcon.bmp"
Content-Type: image/bmp
[REDACTED FILE CONTENTS]
------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream

------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="type"
output
------WebKitFormBoundaryB3sb0uQDOIiNQXCD--

从上面的调试数据中可以看到,只发送了一个文件,并且文件字段为空。我已经测试过了,当两者都被填充时,我收到了相同的结果。

下面是用来捕获表单的onSubmit的JavaScript方法:

$('#attachment-upload form').submit(function (e) {
    e.preventDefault();
    $('#attachment-upload').removeClass('fade').modal('hide');
    $('#attachment-progress').modal('show').addClass('fade');
    $.ajax({
        xhr: function () {
            var xhr = new window.XMLHttpRequest();
            xhr.upload.addEventListener('progress', function (event) {
                if (event.lengthComputable) {
                    var percent = (event.loaded / event.total) * 100;
                    $('#attachment-progress div.modal-body .progress-bar').width(percent);
                    $('#attachment-progress div.modal-body .progress-bar').attr('aria-valuenow', percent);
                    $('#attachment-progress div.modal-body .progress-bar span').html(percent);
                }
            }, false);
            return xhr;
        },
        url: this.action,
        type: 'POST',
        contentType: "multipart/form-data",
        processData: false,
        data: new FormData(this),
        success: function (data) {
            //my success function here
        },
        error: function (jqxhr, status, error) {
            $('#upload-progress-section').addClass('hidden');
            $('#upload-complete-section').removeClass('hidden');
            $('#attachment-progress div.modal-header h1').html("Upload Error");
            $('#upload-complete-section p').html("Upload has failed: " + status + " - " + error);
            $('#attachment-progress div.modal-footer button').removeAttr('disabled');
        }
    });
});

根据我在Fiddler中看到的情况,感觉好像控制器中的方法签名很可能有问题,这导致绑定到参数失败。我很惊讶,虽然FormCollection参数也是空的。

是否有已知的问题使用多部分/表单数据上传文件通过ajax,或者它是什么,我在这里做错了?

MVC 5 Ajax文件上传在控制器中没有反序列化

感谢@DarinDimitrov的提醒,问题是多部分/表单-数据内容类型需要定义边界。

通过设置$.ajax选项contentType: false而不是显式地将其定义为multipart-form/data, ajax方法能够自动插入适当的边界定义,然后控制器能够正确地反序列化数据。