ASP.net MVC 3 - DropDownList not updating during edit?
forgive me as I am fairly new to using ASP.net MVC 3...
I have two tables - one called Contract, one called Sow. Contract has a foreign key that points to SOW. What I'd like to do is to be able to edit the Contract details and provide a drop down list of different SOW records to choose from. The current code:
In my Contract Controller:
public ActionResult Edit(int id)
{
Contract contract = contractRepository.GetContract(id);
var db = new ManagementDataContext();
IEnumerable<SelectListItem> items = db.Sows
.Select(s => new SelectListItem()
{
Value = s.ID.ToString(),
Text = s.Title
});
ViewData["Sow"] = items;
return View(contract);
}
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
Contract contract = contractRepository.GetContract(id);
try
{
UpdateModel(contract);
contractRepository.Save();
return RedirectToAction("Details", new {id = contract.contractID});
}
catch
{
ModelState.AddRuleViolations(contract.GetRuleViolations());
var db = new ManagementDataContext();
IEnumerable<SelectListItem> items = db.Sows
.Select(s => new SelectListItem()
{
Value = s.ID.ToString(),
Text = s.Title
});
ViewData["Sow"] = items;
return View();
}
}
In my Edit.aspx:
<%: Html.DropDownList("Sow") %>
The list populates with values, but when I change them and update, the foreign key does not change. Any advice or help? Also, if you want to throw in a way I could improve my current code?
Again, I apologize for my lack of ASP.net knowledge, but you gotta get your hands dirty and make mistakes in 开发者_运维知识库order to learn.
This is going to generate a select with name="Sow"
.
What you want is the input to have the same name as the FK property you want to bind it too.
Probably something like <%: Html.DropDownList("SowId") %>
Firstly, I highly recommend you to use ViewModel pattern with AutoMapper. Whatever, in you scenario, should work if you do something like
public ActionResult Edit(int id)
{
Contract contract = contractRepository.GetContract(id);
var db = new ManagementDataContext();
IEnumerable<SelectListItem> items = db.Sows
.Select(s => new SelectListItem()
{
Value = s.ID.ToString(),
Text = s.Title
});
ViewData["SowItems"] = items;
return View(contract);
}
Your view:
<%: Html.DropDownList("SowId", ViewData["SowItems"]) %>
the possible problem can be with ModelState and I can't right now give to you a clear explanation.
hope it help you
A few approaches for you to try mixed with some code help.
1st: change your [HttpPost] Edit method to accept a Contract parameter instead of FormCollection, its much cleaner
[HttpPost]
public ActionResult Edit(Contract contract)
As long as the fields of Contract are the names of your input fields, then you are set as the MVC toolkit will map them to a Contract object that is then passed to your Action method. This will also allow you to take advantage of Unobtrusive Validation, meaning MVC framework will validate the data inputs to your model object before it gets to your Action method. You will still have to perform Business Rule validations or Data Model Relational validations, but it helps.
2nd: I prefer to create SelectLists in the View (probably get killed over this), but I think SelectList is definitely a View abstraction of your data which has nothing to do with Control or Model, here's a way to do it, and here's where a ViewModel comes in handy [Side note here for ViewModel, it helps get away from using Strings to pull things out as Objects from ViewData, which in some cases (like SelectLists) need to then be cast in order to compile]
Controller code
var model = new ContractViewModel()
{
Contract = contractRepository.GetContract(id),
Sows = db.Sows.ToList() // ToList() is important here to ensure the data is pulled into the Model
}
// Do any other initializations here
ViewData.Model = model;
return View();
View code
<%= Html.DropDownListFor(model => model.Contract.Sow, new SelectList(Model.Sows, "ID", "Title")) %>
An alternative, if either this won't work for you or you need different validations is:
Controller code
[HttpPost]
public ActionResult Edit(Contract contract, int sowID)
View code
<%= Html.DropDownList("sowID", new SelectList(Model.Sows, "ID", "Title")) %>
Hope this helps.
精彩评论