Mayank Sharma
Mayank Sharma

Reputation: 35

How to Upload an image in the form

I have a form to add a contact, in that form I want to upload the image of the Contact with its other information like name, address, company name etc. So how can I add that image and store the image information to the database. Here is my html form and according to this what will be the Controller..

@using (Html.BeginForm("", "", FormMethod.Post, new { id = "saveContact", enctype = "multipart/form-data" }))
{
<div class="rowElem noborder">
                <label>
                    First name :</label><div class="formRight"><input type="text" id="firstName" name="firstName" value ="@Model.FirstName" style="width: 600px; height:25px;font-size: 16px;" /></div>
                <div class="fix">
                </div>
</div>
<div class="rowElem">
                <label>
                    Upload Image :</label><div class="formRight"><input type="file" id="imageUpload" name="imageUpload" /></div>
                <div class="fix">
                </div>
            </div>
<input type="submit" id="btnAddContact" value="Save" />

Upvotes: 1

Views: 4795

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039398

You could start by definig a view model that will mimic the input fields of your form:

public class ContactViewModel
{
    [DisplayName("First name :")]
    [Required]
    public string FirstName { get; set; }

    [DisplayName("Upload Image :")]
    [Required]
    public HttpPostedFileBase ImageUpload { get; set; }
}

and then have your controller action take this view model as argument:

[HttpPost]
public ActionResult Save(ContactViewModel model)
{
    ...
}

Of course depending on the data access technology that you are using there might be different ways to save the contact to the database. For example if you are using plain ADO.NET you could have a method that does the save:

public int SaveContact(string firstName, byte[] photo)
{
    using (var conn = new SqlConnection("YOUR CONNECTION STRING COMES HERE"))
    using (var cmd = conn.CreateCommand())
    {
        conn.Open();
        cmd.CommandText = "INSERT INTO Contacts (FirstName, Photo) VALUES (@firstName, @photo)";
        cmd.Parameters.AddWithValue("@firstName", firstName);
        cmd.Parameters.Add("@photo", SqlDbType.BigInt, 20).Value = photo;
        return cmd.ExecuteNonQuery();
    }
}

and then inside your controller action you could invoke this method:

[HttpPost]
public ActionResult Save(ContactViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    using (var stream = new MemoryStream())
    {
        model.ImageUpload.InputStream.CopyTo(stream);
        byte[] photo = stream.ToArray();
        SaveContact(model.FirstName, photo);
        return RedirectToAction("Index");
    }
}

Also I would recommend you using HTML helpers in your view to generate the input fields instead of hardcoding them:

@model ContactViewModel
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "saveContact", enctype = "multipart/form-data" }))
{
    <div class="rowElem noborder">
        @Html.LabelFor(x => x.FirstName)
        <div class="formRight">
            @Html.TextBoxFor(x => x.FirstName, new { style = "width: 600px; height:25px;font-size: 16px;" })
            @Html.ValidationMessageFor(x => x.FirstName)
        </div>
       <div class="fix"></div>
    </div>
    <div class="rowElem">
        @Html.LabelFor(x => x.UploadImage)
        <div class="formRight">
            @Html.TextBoxFor(x => x.ImageUpload, new { type = "file" })
            @Html.ValidationMessageFor(x => x.ImageUpload)
        </div>
        <div class="fix"></div>
    </div>
    <input type="submit" id="btnAddContact" value="Save" />    
}

UPDATE:

If you don't want to follow my advice about using view models and have passed directly your domain models to the view and you do not have an ImageUpload property in it and you cannot modify it you could still have the following controller action signature:

[HttpPost]
public ActionResult Save(Contact model, HttpPostedFileBase imageUpload)
{
    ...
}

Upvotes: 4

Related Questions