Saltar al contenido

ASP.NET MVC 4 C # HttpPostedFileBase, ¿Cómo almaceno un archivo?

Por fin luego de mucho luchar pudimos dar con la solución de este enigma que ciertos los lectores de nuestro sitio tienen. Si deseas aportar algún dato no dudes en aportar tu comentario.

Solución:

puede cargar el archivo y guardar su URL en la tabla de la base de datos de esta manera:

Vista:

@using(Html.BeginForm("Create","Assignment",FormMethod.Post,new enctype="multipart/form-data"))

    ...
    
<%: Html.TextBoxFor(model => model.FileLocation, new type="file")%> <%: Html.ValidationMessageFor(model => model.FileLocation) %>
...

Acción:

[HttpPost]
public ActionResult Create(Assignment assignment)

    if (ModelState.IsValid)
    
        if(Request.Files.Count > 0)
        
            HttpPostedFileBase file = Request.Files[0];
            if (file.ContentLength > 0) 
            
                var fileName = Path.GetFileName(file.FileName);
                assignment.FileLocation = Path.Combine(
                    Server.MapPath("~/App_Data/uploads"), fileName);
                file.SaveAs(assignment.FileLocation);
            
            db.Assignments.Add(assignment);
            db.SaveChanges();
            return RedirectToAction("Index");
        
    

    return View(assignment);

Detalles:

Para una mejor comprensión, consulte este buen artículo Cargar un archivo (o archivos) con ASP.NET MVC

Así es como lo hice:

View.cs

@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new enctype = "multipart/form-data" ))

Estaba usando HomeController, entonces creas el Upload funcionar allí. También incluyo cómo puede almacenar el contenido del archivo en la base de datos, no solo la ubicación, y el código a continuación hace uso del Assignment modelo que se proporcionó, pero también mostraré cómo lo guardé en la base de datos en mi caso con un modelo que creé para mi tabla, ITEM_ATCHMT.

No debería tener que pasar un modelo y devolverlo si todo lo que tiene es un control FileUpload en la página y no está completando datos en la vista con él, por lo que esta función no hace eso, y mi Vista no lo hace. No use un modelo: el suyo puede ser diferente y es posible que desee que su modelo se entregue y devuelva, si se usa en su vista.

Configuré el mío para que se publicaran varios objetos a la vez, por lo que tenía un List que recibieron sus datos y serían iterados en el proceso de guardar cada uno de los archivos y sus metadatos en la base de datos. Sin embargo, podría usarlo para guardar un archivo a la vez, así que agregué el código para eso y comenté las partes de los múltiples archivos. Con suerte, no confunde a nadie, solo 2 formas diferentes de hacer lo mismo, al final.

HomeController.cs

    [HttpPost]
    public ActionResult Upload()
    
        //var r = new List();
        var r = new ViewDataUploadFilesResult();
        Assignment a = new Assignment();

        if (ModelState.IsValid)
        
            if (Request.Files.Count > 0)
            
                HttpPostedFileBase file = Request.Files[0];
                if (file.ContentLength > 0)
                
                    int fileSize = file.ContentLength;
                    var fileName = Path.GetFileName(file.FileName);

                    //You could do this to get the content -
                    //it would need a varbinary(max) field 
                    //Stream posted file into a byte array
                    byte[] fileByteArray = new byte[fileSize];
                    file.InputStream.Read(fileByteArray, 0, fileSize);

                    //Uploading properly formatted file to server.
                    string fileLocation = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                    if (!Directory.Exists(Server.MapPath("~/App_Data/uploads")))
                        Directory.CreateDirectory(Server.MapPath("~/App_Data/uploads"));
                    file.SaveAs(fileLocation);

                    // I used a ViewModel to collect my file information
                    ViewDataUploadFilesResult r = new ViewDataUploadFilesResult();
                    r.Name = fileName;
                    r.FilePath = fileLocation;
                    r.Length = fileSize;
                    r.FileObj = file;
                    r.Content = fileByteArray;

                    // I provided a list so I could upload multiple files
                    // at once, but you might've just had the one item, above
                    //r.Add(new ViewDataUploadFilesResult()
                    //
                    //    Name = fileName,
                    //    FilePath = fileLocation,
                    //    Length = fileSize,
                    //    FileObj = file,
                    //    Content = fileByteArray
                    //);

                    // Below is for singular ViewDataUploadFilesResult objects (uncomment the loop for multiple)
                    //for (int i = 0; i < r.Count; i++)
                    //
                        //assignment.FileLocation = r[i].FilePath; //multiple objects need an index, [i]
                        assignment.FileLocation = r.FilePath;  //singular objects don't
                        assignment.Status = "Uploaded";
                        assignment.Comments = "Completed";
                    //

                    // You also could've just not used ViewDataUploadFilesResult 
                    // at all, and just used assignment, only
                    // and just added fileSize, fileContents, etc. to it

                    EFModel db = new EFModel();  // this is your Entity Framework context
                    db.Assignments.Add(assignment);  //"Assignments" would be your table
                    db.SaveChanges();

                

                return RedirectToAction("Index");
                //return View("Index", r);
            
        

        return View();
    

Modelo adicional

ViewDataUploadFilesResult.cs

public class ViewDataUploadFilesResult

    public string Name  get; set; 
    public string FilePath  get; set; 
    public int Length  get; set; 
    public HttpPostedFileBase FileObj  get; set; 
    public byte[] Content  get; set; 

Para mí, en lugar de usar todo este ViewModel, este es un modelo real para mi tabla Attachments:

public partial class ITEM_ATCHMT

    [Key]
    public Guid ATCHMT_ID  get; set; 

    public int ITEM_ID  get; set; 

    [ForeignKey("ITEM_ID")]
    public virtual ITEM item  get; set; 

    [Required]
    [StringLength(50)]
    public string USER_NAME_DESC  get; set; 

    [Required]
    [StringLength(250)]
    public string FILE_NAME_TXT  get; set; 

    [Required]
    public byte[] FILE_CNTNT_CD  get; set; 

    [Required]
    [StringLength(10)]
    public string FILE_TYPE_DESC  get; set; 

    public DateTime CREATED_DT  get; set; 
 

Y di que quería asociarlo con este artículo:

public partial class ITEM

    [Key]
    public int ITEM_ID  get; set; 

    [Required]
    [StringLength(50)]
    public string NAME  get; set; 


Para guardar cualquier dato usando Entity Framework, solo necesita llenar ese modelo, luego hacer un .SaveChanges() en su contexto:

EFModel db = new EFModel();  // this is my Entity Framework context
ITEM item = new ITEM();
item.NAME = "My Item";

db.ITEM.Add(item);  //"ITEM" is my table and name of an EF model, "item" is the object that represents my model
db.SaveChanges();

Y si ITEM_ID está configurado con incremento automático:

ITEM_ATCHMT atchmt_model = new ITEM_ATCHMT();
atchmt_model.ATCHMT_ID = Guid.NewGuid();
atchmt_model.ITEM_ID = item.ITEM_ID // <-- this should have the ID
atchmt_model.USER_NAME_DESC = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
atchmt_model.FILE_CNTNT_CD = r.Content;
atchmt_model.FILE_NAME_TXT = r.Name;
atchmt_model.FILE_TYPE_DESC = r.Name.Split('.')[1];
atchmt_model.CREATED_DT = DateTime.Now;

db.ITEM_ATCHMT.Add(atchmt_model);  //"ITEM_ATCHMT" is my table
db.SaveChanges();

ingrese la descripción de la imagen aquí

Te mostramos reseñas y puntuaciones

Si para ti ha resultado útil nuestro post, agradeceríamos que lo compartas con otros entusiastas de la programación así contrubuyes a dar difusión a esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *