Reputation: 1412
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
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