jQuery ajax файл завантаження у asp.net mvc


78

У мене є файл на моєму перегляді

<form id="upload" enctype="multipart/form-data">
   <input type="file" name="fileUpload" id="fileUpload" size="23" />
</form>

і запит ajax

$.ajax({
    url: '<%=Url.Action("JsonSave","Survey")  %>',
    dataType: 'json',
    processData: false,
    contentType: "multipart/mixed",
    data: {
        Id: selectedRow.Id,
        Value: 'some date was added by the user here :))'
    },
    cache: false,
    success: function (data) {}
});

але у файлі Request.Files немає файлу . Що не так із запитом ajax?


json не може завантажувати подібні файли. Краще використовувати поведінку завантаження за замовчуванням у браузерах.
Хоган

Відповіді:


136

Завантажте файли за допомогою AJAX у ASP.Net MVC

З HTML5 все змінилося

JavaScript

document.getElementById('uploader').onsubmit = function () {
    var formdata = new FormData(); //FormData object
    var fileInput = document.getElementById('fileInput');
    //Iterating through each files selected in fileInput
    for (i = 0; i < fileInput.files.length; i++) {
        //Appending each file to FormData object
        formdata.append(fileInput.files[i].name, fileInput.files[i]);
    }
    //Creating an XMLHttpRequest and sending
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/Home/Upload');
    xhr.send(formdata);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    }
    return false;
}   

Контролер

public JsonResult Upload()
{
    for (int i = 0; i < Request.Files.Count; i++)
    {
        HttpPostedFileBase file = Request.Files[i]; //Uploaded file
        //Use the following properties to get file's name, size and MIMEType
        int fileSize = file.ContentLength;
        string fileName = file.FileName;
        string mimeType = file.ContentType;
        System.IO.Stream fileContent = file.InputStream;
        //To save file, use SaveAs method
        file.SaveAs(Server.MapPath("~/")+ fileName ); //File will be saved in application root
    }
    return Json("Uploaded " + Request.Files.Count + " files");
}

EDIT : HTML

<form id="uploader">
    <input id="fileInput" type="file" multiple>
    <input type="submit" value="Upload file" />
</form>

1
Чи можете ви додати код представлення даних? HTML .. на цю відповідь.
Eric Bishard

Хороший блог Ajeesh! Дякую!
Eric Bishard

1
Привіт, чи є спосіб пов’язати завантажені файли в модель?
Yorro

Це не працює в IE. IE передає повний локальний шлях користувача в параметрі file.FileName, тому вам буде потрібно Path.GetFileName (file.FileName), щоб бути в безпеці. В іншому випадку фантастична відповідь. Велика допомога, дякую.
Лі Річардсон,

посилання в цій відповіді (та інше в коментарі) порушено
DLeh

42

Завантаження файлів AJAX тепер можливе, передавши FormDataоб’єкт у dataвластивість $.ajaxзапиту.

Оскільки OP спеціально попросив реалізацію jQuery, ось:

<form id="upload" enctype="multipart/form-data" action="@Url.Action("JsonSave", "Survey")" method="POST">
    <input type="file" name="fileUpload" id="fileUpload" size="23" /><br />
    <button>Upload!</button>
</form>
$('#upload').submit(function(e) {
    e.preventDefault(); // stop the standard form submission

    $.ajax({
        url: this.action,
        type: this.method,
        data: new FormData(this),
        cache: false,
        contentType: false,
        processData: false,
        success: function (data) {
            console.log(data.UploadedFileCount + ' file(s) uploaded successfully');
        },
        error: function(xhr, error, status) {
            console.log(error, status);
        }
    });
});
public JsonResult Survey()
{
    for (int i = 0; i < Request.Files.Count; i++)
    {
        var file = Request.Files[i];
        // save file as required here...
    }
    return Json(new { UploadedFileCount = Request.Files.Count });
}

Більше інформації про FormData на MDN


7
Гарний. Дякую! Найкраща відповідь, яку я знайшов на НЕКОЛЬКО запитань.
Джесс

1
Я прийшов сюди спеціально, шукаючи рішення jQuery, і був трохи розчарований, побачивши, що відповідь, позначена як Answered, використовувала лише ванільний JavaScript. Ваше рішення чудове і дуже добре працює для мене. Велике спасибі :)
Джошуа К

Зверніть увагу, що якщо ви не вибрали файл, ви все одно отримуєте один файл у масиві з ContentLength = 0
Savage

1
@Savage: протестовано в 2020 / chrome / asp net core mvc: файл є нульовим, якщо ви нічого не вибрали. У будь-якому разі, відповідь - справді чиста інтеграція завантаження файлів з бритвою та контролером MVC
christophe.chapron

4

Ви не можете завантажувати файли через ajax, вам потрібно скористатися iFrame або якоюсь іншою хитрістю, щоб зробити повний зворотний зв’язок. В основному це пов’язано з проблемами безпеки.

Ось гідний запис, включаючи зразок проекту з використанням SWFUpload та ASP.Net MVC Стіва Сандерсона. Це перше, що я прочитав, щоб це правильно працювало з Asp.Net MVC (я тоді також був новим у MVC), сподіваюся, це так само корисно для вас.


13
Це не правда; Ви можете надіслати дані форми через ajax.
Джош М.

@JoshM. Так, але ви не можете надсилати файли через AJAX без якогось зовнішнього рішення.
Kehlan Krumme

8
@kehrk: За допомогою нових об’єктів FormData та File у HTML5 ви дійсно можете завантажувати файли через AJAX. Спробуйте це: developer.mozilla.org/en-US/docs/… .
jrista

1

У мене є такий зразок у версії vuejs: v2.5.2

<form action="url" method="post" enctype="multipart/form-data">
    <div class="col-md-6">
        <input type="file" class="image_0" name="FilesFront" ref="FilesFront" />
    </div>
    <div class="col-md-6">
        <input type="file" class="image_1" name="FilesBack" ref="FilesBack" />
    </div>
</form>
<script>
Vue.component('v-bl-document', {
    template: '#document-item-template',
    props: ['doc'],
    data: function () {
        return {
            document: this.doc
        };
    },
    methods: {
        submit: function () {
            event.preventDefault();

            var data = new FormData();
            var _doc = this.document;
            Object.keys(_doc).forEach(function (key) {
                data.append(key, _doc[key]);
            });
            var _refs = this.$refs;
            Object.keys(_refs).forEach(function (key) {
                data.append(key, _refs[key].files[0]);
            });

            debugger;
            $.ajax({
                type: "POST",
                data: data,
                url: url,
                cache: false,
                contentType: false,
                processData: false,
                success: function (result) {
                    //do something
                },

            });
        }
    }
});
</script>

криваве пекло, я витратив більшу частину двох днів, обертаючи голову навколо цієї проблеми, і ось рішення. Чи можна моделювати прив'язку форми?
Marqueone

0

Якщо ви публікуєте форму за допомогою ajax, тоді ви не можете надіслати зображення за допомогою методу $ .ajax, вам потрібно використовувати класичний метод xmlHttpobject для збереження зображення, інша його альтернатива - використовувати тип submit замість кнопки

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.