ASP.NET DropDownList EditorTemplate
-
10-10-2019 - |
Pregunta
Cada vez que añadir una nueva aplicación Se crea un nuevo AppCategory . Estoy seriamente atornillar esto de alguna manera
marco de código primera entidad de objetos
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; }
}
Editor de plantillas (me encantaría simplemente hacer una sola clave EditorTemplate Exterior)
@inherits System.Web.Mvc.WebViewPage
@Html.DropDownList("Category", LIG2010RedesignMVC3.Models.Repo.GetAppCategoriesSelect())
y por supuesto el repositorio
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();
}
Cada vez que añadir una nueva aplicación Se crea un nuevo AppCategory Estoy seriamente atornillar esto de alguna manera
La adición de más información de depuración
@inherits System.Web.Mvc.WebViewPage
@Html.DropDownList("", LIG2010RedesignMVC3.Models.Repo.GetAppCategoriesSelect())
me da un mensaje de validación en el post
Parameters application/x-www-form-urlencoded
Category 1
Name 8
Error de validación El valor '1' no es válido.
Esto tiene sentido porque Categoría no debe ser un objeto entero.
código del controlador como se pidió bastante seguro de que esto no es el problema, ya que venía de MVCScaffold
[HttpPost]
public ActionResult Create(App d)
{
if (ModelState.IsValid)
{
context.Apps.Add(d);
context.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
Solución
Mi modelo era correcto, era hasta ... ICollection virtual y sólo el ID de clave externa para la sub y todo funcionaba ... cambios siguientes
Modelo
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();
}
Otros consejos
Si se unen a su DROPDOWNLIST Category.Id, que al menos obtendrá el valor seleccionado en ese presentada, pero nada más en la categoría de objetos.
El aglutinante modelo no puede crear el objeto AppCategory
de la colección de forma en su acción Create
porque el formulario sólo tiene un ID para ese objeto (las otras propiedades de AppCategory
no existen).
La solución más rápida sería establecer la propiedad Category
de su objeto App
manualmente, como esto:
[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();
}