MVC 4 Razor File Upload

249

Soy nuevo en MVC 4 y estoy tratando de implementar el Control de carga de archivos en mi sitio web. No puedo encontrar el error. Obtengo un valor nulo en mi archivo.

Controlador:

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

Ver:

@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" />
}
Liam
fuente
posible duplicado de File Upload ASP.NET MVC 3.0
Liam
1
solo tiene que cambiar la subida pública de ActionResult (archivo HttpPostedFileBase) <input type = "file" name = "FileUpload" />
Muhammad Asad
mira
2
Perder enctypeel formulario me costó una hora
Salvaje
¿Dónde está la conexión entre el método Upload () y el botón? ¿Debería haber un evento onClick? Nuevo en asp.net Soy
pnizzle

Respuestas:

333

El parámetro Uploaddel método HttpPostedFileBasedebe tener el mismo nombre que el file input.

Entonces solo cambie la entrada a esto:

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

Además, puede encontrar los archivos en 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");
 }
Cristi Pufu
fuente
2
¿no será por Index out of boundsexcepción en caso de que no haya ningún archivo en la Request.Filescolección ...?
shashwat
2
En realidad lanzará ArgumentOutOfRangeException, pero tienes razón, actualicé
Cristi Pufu
2
Recuerde que los parámetros del Html.BeginForm son el nombre de la acción y el nombre del controlador (sin el postfix 'controlador'. Por ejemplo: Inicio en lugar de HomeController). Otra cosa importante es no incluir la etiqueta <form> dentro, porque es el BeginForm que abre la etiqueta
pocjoc
55
En otras palabras: el nombre de la propiedad del modelo de vista debe coincidir con el nombre del tipo de entrada. Si viewmodelse nombra su propiedad, AgentPhotoentonces debe tener lo siguiente en su vista:<input type="file" name="AgentPhoto"/>
Dayan
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);, la clase "Servidor" no encontrada, ¿qué paquete utiliza?
Danilo Pádua
65

Aclarándolo. Modelo:

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

Publicar acción

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, el método de Extensión para verificar el 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;
         }        
     }
 }
Bishoy Hanna
fuente
archivo adjunto public HttpPostedFileBase {get; conjunto; } / archivo adjunto no es una identidad
Codeone
Creo que Cola se refiere al tipo de archivo adjunto que no se define.
Karson
2
La vista se puede usar según lo descrito por user2028367. En realidad, olvidé incluir el nuevo {enctype = "multipart / form-data"} en la parte Html.BeginForm, por lo que no pude ver el archivo en mi acción. Gran respuesta. +1 para mostrar en clase de modelo y método de extensión.
Arjun
@BishoyHanna Cómo pongo, en mi formulario, el archivo adjunto. Para los otros valores, razor nos proporciona una sintaxis simple, pero ¿cómo lo hago para este archivo?
Denis V
1
hola, @ClintEastwood, esa publicación fue para subir un archivo, busqué en línea algo que coincida con varias cargas (para ti) y encontré la que creo que funcionaría. Nuevamente, su modelo está basado y no está usando "Request.Files" stackoverflow.com/questions/36210413/…
Bishoy Hanna
17

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

archivo de comandos

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

En el controlador

    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase file)
    {

    }
Jagadisha BS
fuente
2
Estoy de acuerdo con @Muflix, no necesitas AJAXaquí. Html.BeginFormhace el trabajo ya. AJAX solo es necesario si no desea una redirección a la<form action=LINK>
jAC
1
Ajax es mejor para archivos más grandes, ya que le permite mejorar la experiencia del usuario.
markthewizard1234
6

solo tiene que cambiar el nombre de su entrada archivada porque se requiere el mismo nombre en el parámetro y el nombre del campo de entrada simplemente reemplace esta línea Su código funciona bien

 <input type="file" name="file" />
Muhammad Asad
fuente
2

Creo que la mejor manera es usar HttpPostedFileBase en su controlador o API. Después de esto, puede detectar simplemente el tamaño, el tipo, etc.

Propiedades de archivo que puede encontrar aquí:

MVC3 Cómo verificar si HttpPostedFileBase es una imagen

Por ejemplo 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();  
}

Espero que sea de ayuda.

Petr Tomášek
fuente
¿Mejor que que? El OP ya está usando HttpPostedFileBase.
jpaugh 05 de