Reputation: 215
This is my index.cshtml
:
<div class="form-group">
@Html.LabelFor(model => model.MembershipID, "MembershipID", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("items", new SelectList((IEnumerable<SelectListItem>)ViewData["MembershipID"]), new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.MembershipID, "", new { @class = "text-danger" })
</div>
This is my StudentController.cs
:
public ActionResult Create()
{
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem { Text = "Child", Value = "0" });
items.Add(new SelectListItem { Text = "Teen", Value = "1" });
items.Add(new SelectListItem { Text = "Adult", Value = "2" });
items.Add(new SelectListItem { Text = "Other", Value = "3" });
items.Add(new SelectListItem { Text = "check", Value = "4" });
ViewData["MembershipID"] = items;
return View();
}
Controller post method:
[HttpPost]
public ActionResult Create(Student student)
{
try
{
// TODO: Add insert logic here
using (BlackBeardDBEntities db = new BlackBeardDBEntities())
{
db.Students.Add(student);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Upvotes: 1
Views: 2201
Reputation: 16701
Update
From your comment below I can see you have this piece of code:
[HttpPost]
public ActionResult Create(Student student)
{
...
return RedirectToAction("Index");
...
}
You are performing a redirect here. ViewData
only lives for a single request, so what's happening is when the browser redirects to the Index
action the ViewData
is empty (because it was sent in the request which told the browser to redirect).
This is why you should not use ViewData
for these types of task, use a ViewModel instead.
However, to solve your problem don't redirect. Just return the Index
view straight from the Create
POST method (remember the data must be passed to the view with each request, so you will need to populate ViewData["MembershipID"]
again):
[HttpPost]
public ActionResult Create(Student student)
{
...
// populate ViewData here, before returning the view
ViewData["MembershipID"] = GetItems();
return View("Index");
...
}
Create a method (GetItems
in my example, I'll leave the implementation details to you) to return the items since you use them in multiple places.
ViewData
will be preserved in this request since it's returning straight to Index
rather than performing a redirect.
Upvotes: 1
Reputation: 843
From the above conversation, you could have your controller as follows
public class StudentsController : Controller
{
private void _SetViewData()
{
List<SelectListItem> items = new List<SelectListItem>();
items.Add(new SelectListItem { Text = "Child", Value = "0" });
items.Add(new SelectListItem { Text = "Teen", Value = "1" });
items.Add(new SelectListItem { Text = "Adult", Value = "2" });
items.Add(new SelectListItem { Text = "Other", Value = "3" });
items.Add(new SelectListItem { Text = "check", Value = "4" });
ViewData["MembershipID"] = items;
}
// GET: Students
public ActionResult Index()
{
// In case your index view uses viewdata, call _SetViewData() if not remove.
_SetViewData();
return View();
}
// GET: Students/Create
public ActionResult Create()
{
_SetViewData();
return View();
}
[HttpPost]
public ActionResult Create(Student student)
{
try
{
// TODO: Add insert logic here
using (BlackBeardDBEntities db = new BlackBeardDBEntities())
{
db.Students.Add(student); db.SaveChanges();
}
return RedirectToAction("Index");
}
catch {
// Either you can redirect to the action which will reload the viewdata
// return RedirectToAction("Create");
// OR you could load the viewdata and use the same view
_SetViewData();
return View();
}
}
}
Here, you may use a private method to set your viewdata needed for an action. If you are returning the view, call this method to set viewdata if not, redirect to Create action which will call the get action and sets the viewdata.
Hope this helps you.
Upvotes: 0