2011-02-19 13 views
11

Encontré muchos artículos sobre esto, pero todavía no sé exactamente cómo hacer esto. Intento crear mi propio motor de blog, tengo Vista para crear artículo (estoy usando EF y Código primero) y ahora debo completar el número de categoría en el que se debe agregar el artículo, pero quiero cambiarlo a lista desplegable con los nombres de categorías. Mi modelo se ve así:Asp.Net MVC3 - Cómo crear Dynamic DropDownList

public class Article 
{ 
    public int ArticleID { get; set; } 
    [Required] 
    public string Title { get; set; } 
    [Required] 
    public int CategoryID { get; set; } 
    public DateTime Date { get; set; } 
    [Required()] 
    [DataType(DataType.MultilineText)] 
    [AllowHtml] 
    public string Text { get; set; } 
    public virtual Category Category { get; set; } 
    public IEnumerable<SelectListItem> Categories { get; set; } 
    public virtual ICollection<Comment> Comments { get; set; } 
} 
public class Category 
{ 
    public int CategoryID { get; set; } 
    [Required] 
    public string Name { get; set; } 
    public virtual ICollection<Article> Articles { get; set; } 

} 

Sé que debo usar Enum (o creo) pero no estoy exactamente seguro de cómo. No sé qué tutorial de lo que encontré es mejor para mí.


Editar:

Gracias por sus respuestas, pero me encontré con algo más. Estoy tratando esto:

Ésta es mi modelo:

public class Article 
{ 
    [Key] 
    public int ArticleID { get; set; } 

    [Display(Name = "Title")] 
    [StringLength(30, MinimumLength = 5)] 
    [Required] 
    public string Title { get; set; } 

    public DateTime Date { get; set; } 

    public int CategoryID { get; set; } 

    [Required()] 
    [DataType(DataType.MultilineText)] 
    [AllowHtml] 
    public string Text { get; set; } 

    public Category Category { get; set; } 

    public virtual ICollection<Comment> Comments { get; set; } 

    public IEnumerable<Category> Categories { get; set; } 
} 
public class Category 
{ 
[Key] 
    public int CategoryId { get; set; } 
    [Required] 
public string CategoryName { get; set; } 
    public virtual ICollection<Article> Articles { get; set; } 

} 

Ésta es mi controlador para crear el artículo:

public ActionResult Vytvorit() 
{ 
    IEnumerable<Category> categories = GetCaregories(); 
    var view = View(new Article() { Categories = categories }); 
    view.TempData.Add("Action", "Create"); 

    return view; 

} 

private static IEnumerable<Category> GetCaregories() 
{ 
    IEnumerable<Category> categories; 
    using (BlogDBContext context = new BlogDBContext()) 
    { 
     categories = (from one in context.Categories 
         orderby one.CategoryName 
         select one).ToList(); 
    } 
    return categories; 
} 

private Category GetCategory(int categoryID) 
{ 
     return db.Categories.Find(categoryID); 
} 
// 
// POST: /Clanky/Vytvorit 

[HttpPost] 
public ActionResult Vytvorit(Article newArticle) 
{ 

    try 
    { 
     if (newArticle.CategoryID > 0) 
     { 
      newArticle.Category = GetCategory(newArticle.CategoryID); 
     } 
     if (TryValidateModel(newArticle)) 
     { 
       db.Articles.Add(newArticle); 
       db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     else 
     { 
      newArticle.Categories = GetCaregories(); 
      var view = View(newArticle); 
      view.TempData.Add("Action", "Create"); 
      return view; 
     } 
    } 
    catch 
    { 
     return View(); 

    } 
} 

y esto es parte de mi punto de vista:

 @Html.DropDownListFor(model => model.CategoryID, new SelectList(Model.Categories,"CategoryID","CategoryName")) 
     @Html.ValidationMessageFor(model => model.CategoryID) 

Tengo un problema con NullReferenceExeption pero no sé por qué. ¿Puedo hacerlo de esta manera? Me parece muy fácil.

+0

¿Solo tiene que utilizar el que obtiene de la caja con jQuery UI? – CarneyCode

Respuesta

20

Su modelo parece bastante extraño. Contiene propiedades como CategoryID y Category que parecen redundantes. También contiene una propiedad de la colección SelectListItem llamada Categories. Entonces, ¿es este un modelo o un modelo de vista? Se ve bastante desordenado. Supongamos que es un modelo. En este caso, sería más probable que vea algo como esto:

public class Article 
{ 
    public int ArticleID { get; set; } 

    [Required] 
    public string Title { get; set; } 

    public DateTime Date { get; set; } 

    [Required()] 
    [DataType(DataType.MultilineText)] 
    [AllowHtml] 
    public string Text { get; set; } 

    public virtual Category Category { get; set; } 

    public IEnumerable<Category> Categories { get; set; } 

    public virtual ICollection<Comment> Comments { get; set; } 
} 

public class Category 
{ 
    public int CategoryID { get; set; } 

    [Required] 
    public string Name { get; set; } 

    public virtual ICollection<Article> Articles { get; set; } 

} 

Ahora que el modelo está claro que podríamos definir un modelo de vista que se pasará a la vista. Un modelo de vista es una clase que está específicamente diseñada para la vista. Entonces, dependiendo de lo que piense poner en esta vista, defínala en este modelo de vista. Hasta ahora se ha hablado sólo de un menú desplegable, así que vamos a hacerlo:

public class ArticleViewModel 
{ 
    public int SelectedCategoryId { get; set; } 
    public IEnumerable<SelectListItem> Categories { get; set; } 
} 

y entonces tenemos un controlador:

public class ArticlesController: Controller 
{ 
    private readonly IArticlesRepository _repository; 
    public ArticlesController(IArticlesRepository repository) 
    { 
     _repository = repository; 
    } 

    public ActionResult Index() 
    { 
     Article article = _repository.GetArticle(); 
     ArticleViewModel viewModel = Mapper.Map<Article, ArticleViewModel>(article); 
     return View(viewModel); 
    } 
} 

así que el controlador utiliza un repositorio para buscar el modelo, lo asigna a un modelo de vista (en este ejemplo utilizo AutoMapper) y pasa a la vista del modelo a la vista que se encargará de demostrarlo:

@model AppName.Models.ArticleViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.DropDownListFor(
     x => x.SelectedCategoryId, 
     new SelectList(Model.Categories, "Value", "Text"), 
     "-- Select category --" 
    ) 
    <input type="submit" value="OK" /> 
} 
+1

Creo que las propiedades CategoryID y Category no son redundantes. Simplemente le está diciendo a Entity Framework que nombre la clave externa como "CategoryID", no la predeterminada "Category_ID" que tiene un guión bajo. – rajeemcariazo

4

he pasado por esto, así y tengo que estar de acuerdo que al principio parece extraño (en mi explicación supongo que quieres seleccionar solo una categoría, pero el proceso es muy similar para una selección múltiple).

Básicamente lo que necesita para llevar a cabo 3 pasos:

1:
Se necesitan dos propiedades en el modelo de vista Una contendrá el ID categoría seleccionada (necesario para la devolución de datos) y el otro será un SelectList con toda posibles categorías:

public class Article 
{ 
    public int ArticleID { get; set; } 

    public int CategoryID { get; set; } 

    public SelectList Categories { get; set; } 
} 

2:
también antes de pasar el modelo de vista a la vista que se tiene que inicializar el SelectList (Mejor practivce es preparar tanto como sea posible antes de pasar a un modelo en la vista):

new SelectList(allCategories, "CategoryID", "Name", selectedCategoryID) 

3:
En la vista es necesario agregar un ListBox para la propiedad CategoryID, pero utilizando la propiedad Categories también llenar el ListBox con los valores:

@Html.ListBoxFor(model => model.CategoryID , Model.Categories) 

Eso es todo! En la acción posterior a la publicación del controlador, tendrá el conjunto de ID de categoría. Puede hacer lo que necesite desde allí para persistir en su db.