ASP.NET EditorTemplate DropdownList
Каждый раз, когда я добавляю новое приложение, создается новая категория приложений. Я серьезно как-то облажался
кодировать объекты структуры первого лица
public class AppCategory
{
public int ID { get; set; }
public string Name { get; set; }
public ICollection<App> apps { get; set; }
}
public class App
{
public int ID { get; set; }
public string Name { get; set; }
public AppCategory Category { get; set; }
}
Шаблон редактора (я бы хотел сделать только один шаблон внешнего ключа EditorTemplate)
@inherits System.Web.Mvc.WebViewPage
@Html.DropDownList("Category", LIG2010RedesignMVC3.Models.Repo.GetAppCategoriesSelect())
и, конечно, хранилище
public static IEnumerable<SelectListItem> GetAppCategoriesSelect()
{
return (from p in GetAppCategories()
select new SelectListItem
{
Text = p.Name,
Value = p.ID.ToString(),
});
}
public static ICollection<AppCategory> GetAppCategories()
{
var context = new LIGDataContext();
return context.AppCategories.ToList();
}
Каждый раз, когда я добавляю новое приложение, оно создает новую категорию приложений, я серьезно как-то облажался
Добавление дополнительной отладочной информации
@inherits System.Web.Mvc.WebViewPage
@Html.DropDownList("", LIG2010RedesignMVC3.Models.Repo.GetAppCategoriesSelect())
дает мне сообщение проверки на сообщение
Parameters application/x-www-form-urlencoded
Category 1
Name 8
Ошибка проверки . Значение '1' недопустимо.
Это имеет смысл, потому что Category должен быть объектом, а не целым числом.
Код контроллера в том виде, в котором его попросили, уверен, что это не проблема, так как он получен от MVCScaffold
[HttpPost]
public ActionResult Create(App d)
{
if (ModelState.IsValid)
{
context.Apps.Add(d);
context.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
3 ответа
Моя модель была неправильно настроена... виртуальная ICollection и только идентификатор внешнего ключа для сабвуфера, и все работало... изменения ниже
модель
public class AppCategory
{
public int ID { get; set; }
public string Name { get; set; }
public **virtual** ICollection<App> Apps { get; set; }
}
public class App
{
public int ID { get; set; }
********************************************
[UIHint("AppCategory")]
public int AppCategoryID { get; set; }
********************************************
public string Name { get; set; }
}
public class LIGDataContext : DbContext
{
public DbSet<AppCategory> AppCategories { get; set; }
public DbSet<App> Apps { get; set; }
}
/Views/Shared/EditorTemplates/AppCategory.cshtml
@inherits System.Web.Mvc.WebViewPage
@Html.DropDownList("", LIG2010RedesignMVC3.Models.Repo.GetAppCategoriesSelect())
AppController
[HttpPost]
public ActionResult Create(App d)
{
if (ModelState.IsValid)
{
this.repository.Add(d);
this.repository.Save();
return RedirectToAction("Index");
}
return View();
}
Если вы свяжете свой dropDownList с Category.Id, вы по крайней мере получите выбранное значение в этом поле, но ничего больше в вашем объекте категории.
Связыватель модели не может создать AppCategory
объект из коллекции форм в вашем Create
действие, потому что форма имеет только идентификатор для этого объекта (другие свойства AppCategory
не там).
Самым быстрым решением будет установка Category
собственность вашего App
объект вручную, вот так:
[HttpPost]
public ActionResult Create(App d) {
int categoryId = 0;
if (!int.TryParse(Request.Form["Category"] ?? String.Empty, out categoryId) {
// the posted category ID is not valid
ModelState.AddModelError("Category",
"Please select a valid app category.")
} else {
// I'm assuming there's a method to get an AppCategory by ID.
AppCategory c = context.GetAppCategory(categoryID);
if (c == null) {
// couldn't find the AppCategory with the given ID.
ModelState.AddModelError("Category",
"The selected app category does not exist.")
} else {
// set the category of the new App.
d.Category = c;
}
}
if (ModelState.IsValid)
{
context.Apps.Add(d);
context.SaveChanges();
return RedirectToAction("Index");
}
return View();
}