C# MVC 4 ASP.net, How to Insert File into Database store in (binary)

WeakTaenie picture WeakTaenie · Aug 6, 2014 · Viewed 9.3k times · Source

Would someone mind to guide me, how to save file into my database, and also retrieve it if possible, I still new to this C# and MVC 4. my databse Assignment contain a attribute call FileLocation which is varBinary ( MAX) .

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; }
    [Range(0,100, ErrorMessage="Only Value between 0-100 is accepted.")]
    public Nullable<decimal> Mark { get; set; }
    public string Comments { get; set; }
    public byte[] FileLocation { get; set; }

    public virtual ICollection<CourseAvailable> CourseAvailables { get; set; }
}
}

Control

[HttpPost]
    public ActionResult Create(Assignment assignment)
    {

        if (ModelState.IsValid)
        {
            db.Assignments.Add(assignment);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(assignment);
    }

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

Answer

Radu Porumb picture Radu Porumb · Aug 6, 2014

You need a bit more processing here. Uploaded files come in as a HttpPostedFileBase, not a byte[] so you need to get the byte[] from the HttpPostedFileBase's InputStream, like so:

[HttpPost]
public ActionResult Create(Assignment assignment)
{
    if(Request.Files != null && Request.Files.Count == 1)
    {
        var file = Request.Files[0];
        if (file != null && file.ContentLength > 0)
        {
            var content = new byte[file.ContentLength];
            file.InputStream.Read(content, 0, file.ContentLength);
            assignment.FileLocation = content;

            // the rest of your db code here
        }
    }
    return RedirectToAction("Create");    
}

P.S. That model looks suspiciously like an Entity object. It's a tremendously bad idea to use Entity objects as your models. Try making an intermediary model and using that to render your data instead.

Edit

In your view, change this:

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

to this:

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

The error you're getting is because the model binder is mistakenly trying to bind your FileLocation field on the page (HttpPostedFileBase type) to the FileLocation field in your model (byte[] type).