Save image to database with ASP.NET MVC

11,634

Try this:

string savedFileName = Server.MapPath("/Resources/images/customers/" + "customers_" + saveCustomer.FirstName + "_" + saveCustomer.LastName + ".jpg");

instead of

string savedFileName = Path.Combine(
                      ConfigurationManager.AppSettings["FileUploadDirectory"],
                      "customers_" + saveCustomer.FirstName + "_" + saveCustomer.LastName + ".jpg");
  1. If your Customer Models contains the Image field, it's not necessary to save to server-side Dirs.

  2. the form post should not have the upload file field, please change the Controller to:

================================

[Authorize]
[HttpPost]
public ActionResult Create([Bind(Exclude = "ImageData")]Customers saveCustomer, HttpPostedFileBase ImageData)
{
    try
    {
        // TODO: Add insert logic here
        var upload = Request.Files["ImageData"];
        string savedFileName = "";  //string for saving the image server-side path          
        if (upload.ContentLength > 0)
        {
             savedFileName = Server.MapPath("/Resources/images/customers/" + "customer_" + saveCustomer.FirstName + "_" + saveCustomer.LastName + ".jpg"); //get the server-side path for store image 
            upload.SaveAs(savedFileName); //*save the image to server-side 
        }
        var index = savedFileName.IndexOf(@"\Resources\");            
        saveCustomer.ImageData = savedFileName.Substring(index, savedFileName.Length - index); //set the string of image server-side path to add-object             
        _db.Customers.InsertOnSubmit(saveCustomer); // save all field to databae (includes image server-side path)
        _db.SubmitChanges();  // save database changes
        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
} 
Share:
11,634
JAML
Author by

JAML

Updated on June 04, 2022

Comments

  • JAML
    JAML almost 2 years

    I am trying to save image to database with Create method. but when try this code, I get this error:

    The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters.*

    I am very beginner to MVC. I will really appreciate for the response, Many thanks in advance.

    [Authorize]
    [HttpPost]
    public ActionResult Create(Customers saveCustomer)
    {
        try
        {
            // TODO: Add insert logic here
            var upload = Request.Files["ImageData"];
            if (upload.ContentLength > 0)
            {
                string savedFileName = Path.Combine(
                      ConfigurationManager.AppSettings["FileUploadDirectory"],
                      "customers_" + saveCustomer.FirstName + "_" + saveCustomer.LastName + ".jpg");
                upload.SaveAs(savedFileName);
            }
            _db.Customers.InsertOnSubmit(saveCustomer);
            _db.SubmitChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }
    

    Here is my create view code:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Reservation.Models.Customers>" %>    
    <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
        Create
    </asp:Content>
    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
        <h2>
            Create</h2>
        <% using (Html.BeginForm("Create", "Customers", FormMethod.Post, new {enctype="multipart/form-data"})) {%>
        <%: Html.ValidationSummary(true) %>
        <fieldset>
            <legend>Add new customer record</legend>
            <div class="editor-label">
                <%: Html.LabelFor(model => model.FirstName) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.FirstName) %>
                <%: Html.ValidationMessageFor(model => model.FirstName) %>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(model => model.LastName) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.LastName) %>
                <%: Html.ValidationMessageFor(model => model.LastName) %>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(model => model.Email) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.Email) %>
                <%: Html.ValidationMessageFor(model => model.Email) %>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(model => model.Phone) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.Phone) %>
                <%: Html.ValidationMessageFor(model => model.Phone) %>
            </div>
            <div class="editor-label">
                <%: Html.LabelFor(model => model.CustomerNote) %>
            </div>
            <div class="editor-field">
                <%: Html.TextBoxFor(model => model.CustomerNote) %>
                <%: Html.ValidationMessageFor(model => model.CustomerNote) %>
            </div>
    
            <div>
               <input type="file" id="ImageData" name="ImageData" />
    
            </div>
    
            <p>
                <input type="submit" value="Add recrod" />
            </p>
        </fieldset>
        <% } %>
        <div>
            <%: Html.ActionLink("Back to List", "Index") %>
        </div>
    </asp:Content>
    

    Web.config:

    <appSettings>
        <add key="FileUploadDirectory" value="~/Resources/images/customers/" />
    </appSettings>
    

    Database entry:

    Column Name  Data Type  Allow Nulls
    ImageData    image      yes 
    
    • bastianwegge
      bastianwegge about 13 years
      You have to convert it before saving it anywhere.
    • JAML
      JAML about 13 years
      Thanks for your reponse, could you please explain, where I can add this code. can you please add the following code into my example. so that I can cleary get clear idea.
    • bastianwegge
      bastianwegge about 13 years
      Could you post the data where the Image is written into the Request?
    • JAML
      JAML about 13 years
      I think this line does it _db.Customers.InsertOnSubmit(saveCustomer); i have posted all code above, there is nothing else in my code, maybe I might be missing that?
  • JAML
    JAML about 13 years
    changed it to your's code, but still getting the same error :-(
  • bastianwegge
    bastianwegge about 13 years
    Since it's nearly the same and you just changed the path... (?)
  • JAML
    JAML about 13 years
    yes that's what I did, changed that one line of code, but no luck, could you please check all my code file, am I doing tha right way?
  • Maidot
    Maidot about 13 years
    Could you give the the Customer "Model", it's contains a Image filed?
  • JAML
    JAML about 13 years
    I am doing this with Linq, I have not created any model for it, I draged the customer table onto my Reservation.dbml file, which is doing this all. I was able to store all the other information, but after adding the image file, I got that error.
  • Maidot
    Maidot about 13 years
    OK, change to my controller, and save image use @wegginho 's Method ~
  • JAML
    JAML about 13 years
    Great I am geeting some where now, I changed it to your controller and debug the programe, it goes fine, but after step [upload.SaveAs(savedFileName);] it goes to catch and skip the following two line: _db.Customers.InsertOnSubmit(saveCustomer); _db.SubmitChanges(); In catch I see this error message The SaveAs method is configured to require a rooted path, and the path '~/Resources/images/customers/customers_uuuuuu_ppppppp.jpg' is not rooted.
  • JAML
    JAML about 13 years
    Please clearify, how can I save image using @wegginho 's Method. where to put that code within controller?
  • Maidot
    Maidot about 13 years
    Sorry that I should hang out about 2 hours : ( , I will give you a exactly answer when I am back.
  • JAML
    JAML about 13 years
    Kool will wait for it then, thanks alot for the help so far:-).
  • JAML
    JAML about 13 years
    It is all working now with the following code, but the only issue is it is not saving the image path to database, so that I can retrive it later. ` string savedFileName = Server.MapPath("/Resources/images/customers/" + "customer_" + saveCustomer.FirstName + "_" + saveCustomer.LastName + ".jpg"); upload.SaveAs(savedFileName);`
  • Maidot
    Maidot about 13 years
    I think the final answer that I posted is fine : ) , please let me know if you have problems~
  • JAML
    JAML about 13 years
    Yes exactly the code worked, but the only issue now is to store the image url in database. could you please confirm, which bit save the image path to database?
  • Maidot
    Maidot about 13 years
    oh~ what kinds of path that stored into database, could you give me the string in database, or it's just empty?
  • JAML
    JAML about 13 years
    Yes it is empty, but now I found the following code tired it, ` byte[] imgBinaryData = new byte[upload.ContentLength]; int readresult = upload.InputStream.Read(imgBinaryData, 0, upload.ContentLength); saveCustomer.ImageData = imgBinaryData;` This only saves [ <Binary data>] string into database, and I need the full url of uploaded image.
  • Maidot
    Maidot about 13 years
    saveCustomer.YourImageColumName = savedFileName; it's doesn't work? that's very strange~ Could you comfirm your ColumName for image path?
  • JAML
    JAML about 13 years
    ImageData is the ColumnName. ** if (upload != null) { if (upload.ContentLength > 0) { byte[] imgBinaryData = new byte[upload.ContentLength]; int readresult = upload.InputStream.Read(imgBinaryData, 0, upload.ContentLength); saveCustomer.ImageData = imgBinaryData; string savedFileName = Server.MapPath("/Resources/images/customers/" + "customer_" + saveCustomer.FirstName + "_" + saveCustomer.LastName + ".jpg"); upload.SaveAs(savedFileName); } }**
  • Maidot
    Maidot about 13 years
    remove those codes: byte[] imgBinaryData = new byte[upload.ContentLength]; int readresult = upload.InputStream.Read(imgBinaryData, 0, upload.ContentLength); saveCustomer.ImageData = imgBinaryData; I change a little bit source code in my post, maybe you can try it~
  • Maidot
    Maidot about 13 years
    you missing saveCustomer.ImageData = savedFileName; before db.Customers.InsertOnSubmit(saveCustomer); , and add string savedFileName=""; before if{}block, and kick "string" in **string savedFileName = Server.MapPath("/Resources/images/customers/" + "customer" + saveCustomer.FirstName + "_" + saveCustomer.LastName + ".jpg"); **
  • JAML
    JAML about 13 years
    Changed the code but the following line gives me error in visual studio, saveCustomer.ImageData = savedFileName; cannot convert source type 'string' ToString() target type 'system.data.linq.binary'
  • Maidot
    Maidot about 13 years
    You should cahnge the Datatype of ImageData to string( nvarchar(200) ), because path is string not a binary data :)
  • JAML
    JAML about 13 years
    Hurry, that worked at last :-). Many many thanks Maidot. it is ready to go. it saved image and image path:-).
  • Maidot
    Maidot about 13 years
    Excellent! I am very happy too~ : )
  • JAML
    JAML about 13 years
    it saves the image full path C:\Users\myPcName\Documents\Visual Studio 2010\Projects\Reservation\Reservation\Resources\images\custo‌​mers\customer_firstn‌​ame_lastname.jpg How can I save only this bit, with forward slashes /Resources/images/customers/customer_firstname_lastname.jpg
  • JAML
    JAML about 13 years
    Yes I have updated it, but still it save with backSlash, but not forward slash. but when I view this Image in [View action] I replace \\ with / and it works. Thanks again:-). Just last question, how can I use the above code for [Edit View] ? for example if I want to Edit existing image? Do I need to post another question for it, or shall we deal with it here?
  • Maidot
    Maidot about 13 years
    that's up to you. If I were you, I will replace it. The only thing we should do is confirm the value of (Request.Files.Count != 0) before we save it, if the value equal to zero, that's means USER doesn't upload any file so we don't need to replace it. : )