thetipsyhacker
thetipsyhacker

Reputation: 1412

Uploading Image to Directory and Writing Image Name to Database

I'm using ASP.NET MVC 4 and I'm trying upload an image to a directory and write the image name to my database; however, the filename is showing up null and I'm getting an Object reference not set to an instance of an object error for the HttpPostedFileBase file variable when it is a parameter in the HttpPost Create() method in my controller.

Here is the filename in the Model:

public string ImageName { get; set; }

This is the View:

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Expense</legend>
<div class="editor-label">
            @Html.LabelFor(model => model.ImageName)
        </div>
        <div class="editor-field">
            <input type="file" name="file" />
        </div>


        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

Here is the HttpPost Create() method in the Controller:

[HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize]
        public ActionResult Create(Expense expense, HttpPostedFileBase file)
        {
            if (ModelState.IsValid)
            {

                var fullName = db.UserProfiles.Where(u => u.UserId == expense.UserId).Select(n => n.FullName).ToArray()[0];

                if (file.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(file.FileName);
                    var path = Path.Combine(Server.MapPath("~/Images/" + fullName), fileName);
                    file.SaveAs(path);
                }

                var query =
                    from e in db.Expenses
                    where e.ExpenseId == expense.ExpenseId
                    select e;

                foreach (Expense exp in query)
                {
                    exp.ImageName = file.FileName;
                }

                db.Expenses.Add(expense);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            var errors = ModelState.Values.SelectMany(v => v.Errors);
            ViewBag.UserId = new SelectList(db.UserProfiles, "UserId", "UserName", expense.UserId);
            return View(expense);
        }

Upvotes: 0

Views: 127

Answers (1)

Geoff James
Geoff James

Reputation: 3180

You will need to make sure that the enctype of the form is set to "multipart/form-data" in order for it to send files to the controller.

In your @Html.BeginForm() method, you need to pass some parameters:

@Html.BeginForm(action,
                controller,
                FormMethod.Post,
                new { enctype="multipart/form-data"}) // <-- Important for uploading files

Where action is the name of the action you're posting to ("Create") in this case, and controller is the name of the controller that action is on (don't know it in your instance, but as an example "ExpenseController").

Also, I like to ensure that the id and name attributes of the <input ... are both set.

Hope this helps!

EDIT
You can also pass null and null as your action and controller params for the Html.BeginForm method, like this:

@Html.BeginForm(null, null, FormMethod.Post, new { enctype="multipart/form-data"})

Upvotes: 2

Related Questions