88

Anyone know of any step by step tutorials on how to upload/display images from a database using Entity Framework? I've checked out code snippets, but I'm still not clear on how it works. I have no code, because aside from writing an upload form, I'm lost. Any (and I mean any) help is greatly appreciated.

On a sidenote, why don't any books cover this topic? I have both Pro ASP.NET MVC 4 and Professional MVC4, and they make no mention of it.

alex
  • 6,818
  • 9
  • 52
  • 103
rogerthat
  • 1,805
  • 4
  • 20
  • 34
  • 6
    If you follow `Pro ASP MVC 4` the `SportsStore Tutorial` does cover this starting on `page 292` – Komengem Apr 27 '13 at 20:24
  • you're right. I didn't even notice. Was looking for a chapter on it. Thanks – rogerthat Apr 27 '13 at 20:38
  • 2
    I know this is for MVC 4, but this question will still show up when looking for MVC 5. - I found a great tutorial which covers both Upload to a Database as Upload to a file server in Mvc 5 using EF 6 on MikesDotNetting http://www.mikesdotnetting.com/article/259/asp-net-mvc-5-with-ef-6-working-with-files – Vahx Apr 24 '16 at 12:40
  • The chapter in the book covers uploading images to the database, where most people want to save the path to the database and the image to a folder. – whisk Oct 26 '16 at 14:04

3 Answers3

144

Have a look at the following

@using (Html.BeginForm("FileUpload", "Home", FormMethod.Post, 
                            new { enctype = "multipart/form-data" }))
{  
    <label for="file">Upload Image:</label> 
    <input type="file" name="file" id="file" style="width: 100%;" /> 
    <input type="submit" value="Upload" class="submit" /> 
}

your controller should have action method which would accept HttpPostedFileBase;

 public ActionResult FileUpload(HttpPostedFileBase file)
    {
        if (file != null)
        {
            string pic = System.IO.Path.GetFileName(file.FileName);
            string path = System.IO.Path.Combine(
                                   Server.MapPath("~/images/profile"), pic); 
            // file is uploaded
            file.SaveAs(path);

            // save the image path path to the database or you can send image 
            // directly to database
            // in-case if you want to store byte[] ie. for DB
            using (MemoryStream ms = new MemoryStream()) 
            {
                 file.InputStream.CopyTo(ms);
                 byte[] array = ms.GetBuffer();
            }

        }
        // after successfully uploading redirect the user
        return RedirectToAction("actionname", "controller name");
    }

Update 1

In case you want to upload files using jQuery with asynchornously, then try this article.

the code to handle the server side (for multiple upload) is;

 try
    {
        HttpFileCollection hfc = HttpContext.Current.Request.Files;
        string path = "/content/files/contact/";

        for (int i = 0; i < hfc.Count; i++)
        {
            HttpPostedFile hpf = hfc[i];
            if (hpf.ContentLength > 0)
            {
                string fileName = "";
                if (Request.Browser.Browser == "IE")
                {
                    fileName = Path.GetFileName(hpf.FileName);
                }
                else
                {
                    fileName = hpf.FileName;
                }
                string fullPathWithFileName = path + fileName;
                hpf.SaveAs(Server.MapPath(fullPathWithFileName));
            }
        }

    }
    catch (Exception ex)
    {
        throw ex;
    }

this control also return image name (in a javascript call back) which then you can use it to display image in the DOM.

UPDATE 2

Alternatively, you can try Async File Uploads in MVC 4.

Idrees Khan
  • 7,702
  • 18
  • 63
  • 111
46

Here is a short tutorial:

Model:

namespace ImageUploadApp.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Image
    {
        public int ID { get; set; }
        public string ImagePath { get; set; }
    }
}

View:

  1. Create:

    @model ImageUploadApp.Models.Image
    @{
        ViewBag.Title = "Create";
    }
    <h2>Create</h2>
    @using (Html.BeginForm("Create", "Image", null, FormMethod.Post, 
                                  new { enctype = "multipart/form-data" })) {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>Image</legend>
            <div class="editor-label">
                @Html.LabelFor(model => model.ImagePath)
            </div>
            <div class="editor-field">
                <input id="ImagePath" title="Upload a product image" 
                                      type="file" name="file" />
            </div>
            <p><input type="submit" value="Create" /></p>
        </fieldset>
    }
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }
    
  2. Index (for display):

    @model IEnumerable<ImageUploadApp.Models.Image>
    
    @{
        ViewBag.Title = "Index";
    }
    
    <h2>Index</h2>
    
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.ImagePath)
            </th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.ImagePath)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ID }) |
                @Ajax.ActionLink("Delete", "Delete", new {id = item.ID} })
            </td>
        </tr>
    }
    
    </table>
    
  3. Controller (Create)

    public ActionResult Create(Image img, HttpPostedFileBase file)
    {
        if (ModelState.IsValid)
        {
            if (file != null)
            {
                file.SaveAs(HttpContext.Server.MapPath("~/Images/") 
                                                      + file.FileName);
                img.ImagePath = file.FileName;
            }  
            db.Image.Add(img);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(img);
    }
    

Hope this will help :)

SteveC
  • 15,808
  • 23
  • 102
  • 173
  • Wow, thank you so much for this. What if I wanted to restrict the image to jpeg? – Kala J Oct 21 '13 at 14:47
  • @KalaJ If you want to restrict the images uploaded to only jpg you can add the accept attribute (Html5 only working in Chrome and FF not IE). Or you can check the extension in controller `filename.LastIndexOf(".")` something like that. Hope this helps – Jordy van Eijk Oct 29 '13 at 17:35
  • @JordyvanEijk, I used the accept attribute however it only works in Chrome. It doesn't work in FF or IE. I need some other form of validation. – Kala J Nov 07 '13 at 12:43
  • 1
    @KalaJ Majbe you can do something with the [Html5 File Api](http://www.w3.org/TR/file-upload/) If you need some tutorial [Here it is](http://www.html5rocks.com/en/tutorials/file/dndfiles/) – Jordy van Eijk Nov 07 '13 at 16:32
  • 2
    Hackers would be able to upload malicious files without server-side validation. – arao6 Sep 21 '14 at 14:22
  • what is db here. It says db is does not exist in current context. – tanz Mar 17 '15 at 08:48
  • @tanz, it's an instance of an [Entity Framework's DbContext class](https://msdn.microsoft.com/library/system.data.entity.dbcontext(v=vs.113).aspx), which is used to access database object in-code. – Deilan Jun 17 '15 at 14:54
  • For the sake of security, you may also need to see this http://stackoverflow.com/a/6388927/900284 – Frank Myat Thu Dec 29 '15 at 14:35
-16
        <input type="file" id="picfile" name="picf" />
       <input type="text" id="txtName" style="width: 144px;" />
 $("#btncatsave").click(function () {
var Name = $("#txtName").val();
var formData = new FormData();
var totalFiles = document.getElementById("picfile").files.length;

                    var file = document.getElementById("picfile").files[0];
                    formData.append("FileUpload", file);
                    formData.append("Name", Name);

$.ajax({
                    type: "POST",
                    url: '/Category_Subcategory/Save_Category',
                    data: formData,
                    dataType: 'json',
                    contentType: false,
                    processData: false,
                    success: function (msg) {

                                 alert(msg);

                    },
                    error: function (error) {
                        alert("errror");
                    }
                });

});

 [HttpPost]
    public ActionResult Save_Category()
    {
      string Name=Request.Form[1]; 
      if (Request.Files.Count > 0)
        {
            HttpPostedFileBase file = Request.Files[0];
         }


    }
user3789888
  • 123
  • 1
  • 2