MVC 4 Razor File Upload


249

Sono nuovo di MVC 4 e sto cercando di implementare il Controllo caricamento file nel mio sito Web. Non riesco a trovare l'errore. Ricevo un valore nullo nel mio file.

controller:

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

Visualizza:

@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" />
}

possibile duplicato di Upload file ASP.NET MVC 3.0
Liam

1
devi solo cambiare il ActionResult Upload pubblico (file HttpPostedFileBase) <input type = "file" name = "FileUpload" />
Muhammad Asad

controlla la mia implementazione qui stackoverflow.com/a/40990080/4251431
Basheer AL-MOMANI

2
Perdere enctypeil modulo mi è costato un'ora
Savage

Dov'è la connessione tra il metodo Upload () e il pulsante. Dovrebbe esserci un evento onClick? Nuovo su asp.net I am
pnizzle

Risposte:


333

Il parametro Uploaddel metodo HttpPostedFileBasedeve avere lo stesso nome del parametro file input.

Quindi basta cambiare l'input in questo:

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

Inoltre, puoi trovare i file in 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
non andrà attraverso l' Index out of boundseccezione nel caso in cui non ci siano file nella Request.Filesraccolta ..?
Shashwat,

2
In realtà lancerà ArgumentOutOfRangeException, ma hai ragione, ho aggiornato
Cristi Pufu il

2
Ricorda che i parametri di Html.BeginForm sono il nome dell'azione e il nome del controller (senza il postfix 'controller'. Ad esempio: Home invece di HomeController). Un'altra cosa importante è non includere il tag <form> all'interno, perché è BeginForm che apre il tag
pocjoc

5
In altre parole: il nome della proprietà del modello di visualizzazione deve corrispondere a quello del nome del tipo di input. Se la tua viewmodelproprietà è denominata AgentPhoto, devi avere i seguenti punti di vista:<input type="file" name="AgentPhoto"/>
Dayan,

var path = Path.Combine(Server.MapPath("~/Images/"), fileName);, la classe "Server" non trovata, quale pacchetto utilizza?
Danilo Pádua,

65

Chiarendolo. Modello:

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

Post azione

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

Finalmente il metodo Extension per controllare 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;
         }        
     }
 }

allegato HttpPostedFileBase pubblico {get; impostato; } / allegato non è un identificativo
Codeone

Penso che Cola si riferisca al tipo di allegato che non viene definito.
Karson,

2
La vista potrebbe essere utilizzata come descritto dall'utente2028367. In realtà ho dimenticato di includere il nuovo {enctype = "multipart / form-data"} nella parte Html.BeginForm, quindi non sono stato in grado di visualizzare il file nella mia azione. Bella risposta. +1 per la visualizzazione in classe Modello e metodo di estensione.
Arjun,

@BishoyHanna Come ho messo, sul mio modulo, l'allegato. Per gli altri valori, il rasoio ci fornisce una semplice sintassi, ma come faccio per questo file?
Denis V,

1
ciao, @ClintEastwood, quel post era per il caricamento di un file, ho cercato online qualcosa che corrispondesse a più caricamenti (per te) e ho trovato quello che penso funzionerebbe. Ancora una volta, il suo modello basato non sta usando "Request.Files" stackoverflow.com/questions/36210413/...
Bishoy Hanna

17

Visualizza pagina

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

file di script

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

Nel controller

    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase file)
    {

    }

2
Sono d'accordo con @Muflix, non è necessario AJAXqui. Html.BeginFormfa già il lavoro. AJAX è necessario solo se non si desidera un reindirizzamento a<form action=LINK>
jAC il

1
Ajax è migliore per file di grandi dimensioni poiché consente di migliorare l'esperienza dell'utente.
markthewizard1234,

6

devi solo cambiare il nome del tuo input archiviato perché lo stesso nome è richiesto nel parametro e nel campo di input name basta sostituire questa riga Il tuo codice funziona bene

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

2

Penso che il modo migliore sia usare HttpPostedFileBase nel tuo controller o API. Dopo questo puoi semplicemente rilevare dimensioni, tipo ecc.

Proprietà dei file che puoi trovare qui:

MVC3 Come verificare se HttpPostedFileBase è un'immagine

Ad esempio 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();  
}

Spero che sia d'aiuto.


Meglio di cosa? L'OP sta già utilizzando HttpPostedFileBase.
jpaugh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.