Хорошо, я перешел через Google, StackOverflow и ASP.net - действительно ли я единственный человек, который этого не понимает?
Грубая проблема = у меня есть объект Employee, который ссылается на объект Office. Ранее я мог создавать новых сотрудников (забил меня молотком за то, что я забыл, как работает этот код), но теперь я просто не могу ни создать сотрудника, ни редактировать существующего.
Теперь вот что я узнал;
1) Убедитесь, что вы добавляете список офисов в ViewBag на каждом шагу
2) Это включает неудачный POST / редактирование; вызовите функцию для повторного заполнения ViewBag списком офисов
3) Я думаю (!!), что вы всегда хотите установить Employee.Office, а не Employee.Office.OfficeID; последнее приводит к «является частью ключевой информации объекта и не может быть изменено» ошибки
Итак, что у меня есть;
Контроллер, который имеет следующий метод;
private void AddOfficesToViewBag()
{
Dictionary<string, Office> list = new Dictionary<string, Office>();
foreach (Office office in company.GetAllOffices())
list.Add(office.ToString(), office);
SelectList items = new SelectList(list, "Value", "Key");
ViewBag.OfficeList = items;
}
Создать пару в виде;
public ActionResult Create()
{
if (company.Offices.Count() < 1)
return RedirectToAction("Create", "Office", (object) "You need to create one or more offices first");
AddOfficesToViewBag();
return View(new Employee());
}
//
// POST: /Employee/Create
[HttpPost]
public ActionResult Create(Employee emp)
{
if (TryUpdateModel<Employee>(emp))
{
company.Employees.Add(emp);
company.SaveChanges();
return RedirectToAction("Index");
}
else
{
AddOfficesToViewBag();
return View(emp);
}
}
и пара редактирования, которая выглядит как;
public ActionResult Edit(int id)
{
Employee emp = company.Employees.Single(e => e.EmployeeID == id);
AddOfficesToViewBag();
return View(emp);
}
//
// POST: /Employee/Edit/5
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
Employee emp = company.Employees.Single(e => e.EmployeeID == id);
if (TryUpdateModel(emp))
{
company.SaveChanges();
return RedirectToAction("Index");
}
else
{
AddOfficesToViewBag();
return View(emp);
}
}
Я выберу вид редактирования, который почти такой же, как и вид создания;
@ using (Html.BeginForm ()) {
@ Html.ValidationSummary (правда)
Сотрудник
@Html.HiddenFor(model => model.EmployeeID)
<div class="editor-label">
@Html.LabelFor(model => model.Office)
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.Office, (SelectList) ViewBag.OfficeList)
@Html.ValidationMessageFor(model => model.Office)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Я бы сказал, что Edit, в частности, выглядит почти там. Ему удается привязать к переданному объекту Employee и установить раскрывающийся список для соответствующей записи.
Просмотр исходного HTML-источника показывает, что выходным значением является значение Office.ToString ().
Странно для меня то, что происходит какое-то волшебство, которое связывает Employee-> Office с правильной записью, что заставляет представление Edit работать, но нет соответствующего преобразования выбранного элемента (строка, aka object-> ToString () ) к исходному списку.
Это кажется настолько простым (MVC / EF4 / DropDownList), что я чувствую, что упускаю что-то невероятно фундаментальное.
Все мысли оценены.
С уважением
Скотт