简体   繁体   English

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

[英]MVC 5 Ajax File Upload Not Deserializing in Controller

For some reason I'm having an issue deserializing the data being sent using the multipart/form-data type. 由于某种原因,我在反序列化使用multipart / form-data类型发送的数据时遇到问题。 This is an MVC 5 project and data is not being mapped into the controller method. 这是一个MVC 5项目,数据未映射到控制器方法中。 The strange part is that in Fiddler all the data appears valid without a problem. 奇怪的是,在Fiddler中,所有数据看起来都是有效的,没有问题。 However, when debugging I can clearly see that the parameters are all null. 但是,在调试时,我可以清楚地看到参数全为空。

This is a form that sends one text field (hidden) and up to two files to the controller. 这是一种将一个文本字段(隐藏)和最多两个文件发送到控制器的形式。 Below is the signature: 以下是签名:

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

The implementation of the method I think is irrelevant for this question since the issue is that the parameters are not being populated. 我认为该方法的实现与该问题无关,因为问题在于未填充参数。

Without posting the mess that is the actual file contents here's the redacted version of the Fiddler output: 在不发布实际文件内容混乱的情况下,这是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--

As you can see in the above debugging data only one file is being sent and the file field is blank. 如您在上面的调试数据中看到的,仅发送一个文件,并且文件字段为空白。 I've tested and I receive the same results when both are populated. 我已经测试过,当两者都填充时,我会收到相同的结果。

Here's the JavaScript method that's being used to capture the onSubmit of the form: 这是用于捕获表单的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');
        }
    });
});

Based on what I'm seeing in Fiddler it feel like there is most likely something wrong with the method signature in the controller, which is causing the binding to the parameters to fail. 根据我在Fiddler中看到的内容,感觉控制器中的方法签名很可能出了点问题,这导致与参数的绑定失败。 I'm surprised though that the FormCollection parameter is null too. 我很惊讶,尽管FormCollection参数也为null。

Are there known issues with using multipart/form-data upload files via ajax, or is it something that I'm doing incorrectly here? 通过ajax使用多部分/表单数据上传文件是否存在已知问题,或者我在这里做错了什么?

Thanks to @DarinDimitrov for the heads up the issue was that the multipart/form-data content type requires a defined boundary. 多亏了@DarinDimitrov的注意,问题在于multipart / form-data内容类型需要定义的边界。

By setting the $.ajax option contentType: false instead of explicitly defining it as multipart-form/data, the ajax method was able to automatically insert the proper boundary definition and the controller was then able to deserialize the data properly. 通过设置$.ajax选项contentType: false而不是将其显式定义为multipart-form / data,ajax方法能够自动插入正确的边界定义,然后控制器能够正确地反序列化数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM