Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 4 C# HttpPostedFileBase, How do I Store File

Model

public partial class Assignment
{
    public Assignment()
    {
        this.CourseAvailables = new HashSet<CourseAvailable>();
    }

    public string AssignmentID { get; set; }
    public Nullable<System.DateTime> SubmissionDate { get; set; }
    public string Status { get; set; }
    public Nullable<decimal> Mark { get; set; }
    public string Comments { get; set; }
    public string FileLocation  { get; set; }
    public virtual ICollection<CourseAvailable> CourseAvailables { get; set; }
}}

Controller

 public ActionResult Create(Assignment assignment)
    {
        if (ModelState.IsValid)
        {


            db.Assignments.Add(assignment);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(assignment);
    }

View

<div class="editor-field">
    <%: Html.TextBoxFor(model => model.FileLocation, new { type="file"})%>
    <%: Html.ValidationMessageFor(model => model.FileLocation) %>
</div>

How do I store a file if I wanted to store the file into the server/path folder and in the database I only want to store the Path name/string.

like image 662
WeakTaenie Avatar asked Aug 04 '14 18:08

WeakTaenie


People also ask

What is Microsoft ASP.NET MVC 4?

ASP.NET MVC 4 is a framework for developing highly testable and maintainable Web applications that follow the Model-View-Controller (MVC) pattern.

Is MVC 6 a core?

MVC 6 was part of ASP.NET 5, but due to some major changes in the code base, they decided to change its name from ASP.NET 5 to ASP.NET Core. Save this answer.

What is an Actionresult C#?

An action result is what a controller action returns in response to a browser request. The ASP.NET MVC framework supports several types of action results including: ViewResult - Represents HTML and markup. EmptyResult - Represents no result. RedirectResult - Represents a redirection to a new URL.

What is ASP.NET MVC C#?

Model View Controller (MVC) MVC is a design pattern used to decouple user-interface (view), data (model), and application logic (controller). This pattern helps to achieve separation of concerns.


2 Answers

you can upload file and save its url in the database table like this:

View:

@using(Html.BeginForm("Create","Assignment",FormMethod.Post,new {enctype="multipart/form-data"}))
{
    ...
    <div class="editor-field">
        <%: Html.TextBoxFor(model => model.FileLocation, new { type="file"})%>
        <%: Html.ValidationMessageFor(model => model.FileLocation) %>
    </div>
    ...
}

Action:

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

Details:

For better understanding refer this good article Uploading a File (Or Files) With ASP.NET MVC

like image 133
Ehsan Sajjad Avatar answered Oct 16 '22 14:10

Ehsan Sajjad


Here's how I did it:

View.cs

<div class="row">

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

</div>

I was using HomeController, so you create the Upload function there. I'm also including how you might store the file contents in the database, not just the location, and the code below makes use of the Assignment model that was provided, but I'll also show how I saved it to the database in my case with a model I created for my table, ITEM_ATCHMT.

You shouldn't have to pass in a model & pass it back if all you have is a FileUpload control on the page and aren't populating data on the view with it, so this function doesn't do that, and my View doesn't use a model - yours may be different and you may want to keep your model being passed in, returned, if used on your view.

I set mine up for multiple objects to be posted at one time, so I had a List<ViewDataUploadFilesResult> that received their data and would get iterated through in the process of saving each of the files and their metadata to the database. You could use it to simply save one file at a time, though, so I've added the code for that and commented out the parts for the multiple files. Hopefully it doesn't confuse anyone - just 2 different ways of doing the same thing, in the end.

HomeController.cs

    [HttpPost]
    public ActionResult Upload()
    {
        //var r = new List<ViewDataUploadFilesResult>();
        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();
    }

Additional Model

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

For me, instead of using this whole ViewModel, this is an actual model for my Attachments table:

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

And say I wanted to associate it with this item:

public partial class ITEM
{
    [Key]
    public int ITEM_ID { get; set; }

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

}

To save any data using Entity Framework, you just need to fill that model, then do a .SaveChanges() on your context:

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

And if ITEM_ID is set up with auto-incrementing:

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

enter image description here

like image 2
vapcguy Avatar answered Oct 16 '22 14:10

vapcguy