Téléchargement de fichier MVC 4 Razor


249

Je suis nouveau sur MVC 4 et j'essaie d'implémenter le contrôle de téléchargement de fichiers sur mon site Web. Je ne trouve pas l'erreur, j'obtiens une valeur nulle dans mon fichier.

Manette:

public class UploadController : BaseController
    {
        public ActionResult UploadDocument()
        {
            return View();
        }

       [HttpPost]
       public ActionResult Upload(HttpPostedFileBase file)
       {
           if (file != null && file.ContentLength > 0)
           {
               var fileName = Path.GetFileName(file.FileName);
               var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
               file.SaveAs(path);
           }

           return RedirectToAction("UploadDocument");
        }
    }

Vue:

@using (Html.BeginForm("Upload", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{ 
    <input type="file" name="FileUpload" />
    <input type="submit" name="Submit" id="Submit" value="Upload" />
}

doublon possible de File Upload ASP.NET MVC 3.0
Liam

1
il vous suffit de modifier le téléchargement ActionResult public (fichier HttpPostedFileBase) <input type = "file" name = "FileUpload" />
Muhammad Asad

consultez mon implémentation ici stackoverflow.com/a/40990080/4251431
Basheer AL-MOMANI

2
Rater enctypele formulaire m'a coûté une heure
Savage

Où est la connexion entre la méthode Upload () et le bouton. Devrait-il y avoir un événement onClick? Nouveau sur asp.net Je suis
pnizzle

Réponses:


333

Le paramètre de Uploadla méthode HttpPostedFileBasedoit avoir le même nom que le file input.

Modifiez donc simplement l'entrée en ceci:

<input type="file" name="file" />

Vous pouvez également trouver les fichiers dans Request.Files:

[HttpPost]
public ActionResult Upload()
{
     if (Request.Files.Count > 0)
     {
         var file = Request.Files[0];

         if (file != null && file.ContentLength > 0)
         {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
            file.SaveAs(path);
         }
     }

     return RedirectToAction("UploadDocument");
 }

2
ne le fera-t-il pas par Index out of boundsexception s'il n'y a pas de fichier dans la Request.Filescollection ..?
shashwat

2
En fait, ça va lancer ArgumentOutOfRangeException, mais vous avez raison, j'ai mis à jour
Cristi Pufu

2
N'oubliez pas que les paramètres de Html.BeginForm sont le nom de l'action et le nom du contrôleur (sans le suffixe «controller». Par exemple: Home au lieu de HomeController). Une autre chose importante est de ne pas inclure la balise <form> à l'intérieur, car c'est le BeginForm qui ouvre la balise
pocjoc

5
En d'autres termes: le nom de la propriété de votre modèle de vue doit correspondre à celui du nom du type d'entrée. Si votre viewmodelpropriété est nommée, AgentPhotovous devez avoir les éléments suivants à votre vue:<input type="file" name="AgentPhoto"/>
Dayan

var path = Path.Combine(Server.MapPath("~/Images/"), fileName);, la classe "Serveur" introuvable, quel package utiliser?
Danilo Pádua

65

Clarifier. Modèle:

public class ContactUsModel
{
    public string FirstName { get; set; }             
    public string LastName { get; set; }              
    public string Email { get; set; }                 
    public string Phone { get; set; }                 
    public HttpPostedFileBase attachment { get; set; }

Après l'action

public virtual ActionResult ContactUs(ContactUsModel Model)
{
 if (Model.attachment.HasFile())
 {
   //save the file

   //Send it as an attachment 
    Attachment messageAttachment = new Attachment(Model.attachment.InputStream,       Model.attachment.FileName);
  }
}

Enfin la méthode d'extension pour vérifier le hasFile

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace AtlanticCMS.Web.Common
{
     public static class ExtensionMethods 
     {
         public static bool HasFile(this HttpPostedFileBase file)
         {
             return file != null && file.ContentLength > 0;
         }        
     }
 }

attachement public HttpPostedFileBase {get; ensemble; } / pièce jointe n'est pas une identité
Codeone

Je pense que Cola fait référence au type de pièce jointe non défini.
Karson

2
La vue peut être utilisée comme décrit par user2028367. En fait, j'ai oublié d'inclure de nouveaux {enctype = "multipart / form-data"} dans la partie Html.BeginForm, donc je n'ai pas pu voir le fichier dans mon action. Très bonne réponse. +1 pour l'affichage dans la classe Model et la méthode Extension.
Arjun

@BishoyHanna Comment j'ai mis, sur mon formulaire, la pièce jointe. Pour les autres valeurs, rasoir nous fournit une syntaxe simple, mais comment le faire pour ce fichier?
Denis V

1
salut, @ClintEastwood, ce message était pour le téléchargement d'un fichier, j'ai cherché en ligne quelque chose qui correspond à plusieurs téléchargements (pour vous) et j'ai trouvé celui qui, selon moi, fonctionnerait. Encore une fois, son modèle basé qui n'utilise pas "Request.Files" stackoverflow.com/questions/36210413/…
Bishoy Hanna

17

Voir page

@using (Html.BeginForm("ActionmethodName", "ControllerName", FormMethod.Post, new { id = "formid" }))
 { 
   <input type="file" name="file" />
   <input type="submit" value="Upload" class="save" id="btnid" />
 }

Fichier de script

$(document).on("click", "#btnid", function (event) {
        event.preventDefault();
        var fileOptions = {
            success: res,
            dataType: "json"
        }
        $("#formid").ajaxSubmit(fileOptions);
    });

Dans le contrôleur

    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase file)
    {

    }

2
Je suis d'accord avec @Muflix, vous n'avez pas besoin AJAXici. Html.BeginFormfait déjà le travail. AJAX n'est nécessaire que si vous ne voulez pas de redirection vers le<form action=LINK>
jAC

1
Ajax est meilleur pour les fichiers plus volumineux car il vous permet d'améliorer l'expérience utilisateur.
markthewizard1234

6

il vous suffit de changer le nom de votre entrée déposée car le même nom est requis dans le paramètre et le nom du champ de saisie il suffit de remplacer cette ligne Votre code fonctionne bien

 <input type="file" name="file" />

2

Je pense que la meilleure façon est d'utiliser HttpPostedFileBase dans votre contrôleur ou votre API. Après cela, vous pouvez simplement détecter la taille, le type, etc.

Les propriétés de fichier que vous pouvez trouver ici:

MVC3 Comment vérifier si HttpPostedFileBase est une image

Par exemple ImageApi:

[HttpPost]
[Route("api/image")]  
public ActionResult Index(HttpPostedFileBase file)  
{  
    if (file != null && file.ContentLength > 0)  
        try 
        {  
            string path = Path.Combine(Server.MapPath("~/Images"),  
               Path.GetFileName(file.FileName));

            file.SaveAs(path);  
            ViewBag.Message = "Your message for success";  
        }  
        catch (Exception ex)  
        {  
            ViewBag.Message = "ERROR:" + ex.Message.ToString();  
        }  
    else 
    {  
        ViewBag.Message = "Please select file";  
    }  
    return View();  
}

J'espère que cela vous aidera.


Mieux que quoi? L'OP utilise déjà HttpPostedFileBase.
jpaugh
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.