87 votes

jQuery ajax upload file dans asp.net mvc

J'ai un fichier dans ma vue

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

et une requête 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) {}
});

mais il n'y a pas de fichier dans le Demande.de.fichiers . Quel est le problème avec la requête ajax ?

0 votes

Json ne peut pas télécharger des fichiers comme celui-ci. Il est préférable d'utiliser le comportement de téléchargement par défaut des navigateurs.

145voto

Ajeesh M Points 777

Télécharger des fichiers en utilisant AJAX en ASP.Net MVC

Les choses ont changé depuis 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;
}   

Contrôleur

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");
}

EDITAR : Le HTML

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

1 votes

Pouvez-vous ajouter le code pour la vue ? le HTML à cette réponse.

0 votes

Beau blog Ajeesh ! Merci !

1 votes

Bonjour, existe-t-il un moyen de lier les fichiers téléchargés dans un modèle ?

54voto

Rory McCrossan Points 69838

Les téléchargements de fichiers en AJAX sont maintenant possibles en passant un fichier FormData à l'objet data de l $.ajax demande.

Comme l'OP a spécifiquement demandé une implémentation de jQuery, voici :

<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 });
}

Plus d'informations sur FormData sur MDN

7 votes

Magnifique. Je vous remercie ! La meilleure réponse que j'ai trouvée à PLUSIEURS questions.

1 votes

Je suis venu ici en cherchant spécifiquement une solution jQuery et j'ai été un peu déçu de voir que la réponse marquée comme répondue n'utilisait que du vanilla JavaScript. Votre solution est géniale et fonctionne très bien pour moi. Merci beaucoup :)

0 votes

Notez que si vous ne sélectionnez pas de fichier, vous obtenez toujours un seul fichier dans le tableau, avec ContentLength = 0.

4voto

Nick Craver Points 313913

Vous ne pouvez pas télécharger de fichiers via ajax, vous devez utiliser un iFrame ou une autre astuce pour effectuer un postback complet. Ceci est principalement dû à des questions de sécurité.

Voici un article décent comprenant un exemple de projet. en utilisant SWFUpload et ASP.Net MVC par Steve Sanderson. C'est la première chose que j'ai lue pour que cela fonctionne correctement avec Asp.Net MVC (j'étais également novice en MVC à l'époque), j'espère qu'elle vous sera aussi utile.

15 votes

Ce n'est pas vrai ; vous pouvez envoyer les données du formulaire par ajax.

0 votes

@JoshM. Oui, mais vous ne pouvez pas envoyer des fichiers via AJAX sans une sorte de solution externe.

9 votes

@kehrk : Avec les nouveaux objets FormData et File de HTML5, vous pouvez effectivement télécharger des fichiers via AJAX. Essayez ceci : developer.mozilla.org/en-US/docs/ .

1voto

J'ai un échantillon comme celui-ci sur vuejs version : 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>

0 votes

Bon sang, j'ai passé la majeure partie de deux jours à me pencher sur ce problème, et voici une solution. Est-il possible de lier le formulaire par un modèle ?

0voto

CoffeeCode Points 1863

J'ai trouvé un excellent plugin pour l'affichage des fichiers et des formulaires via ajax - Plugin jQuery Form

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X