2011-02-19 16 views
11

Ho trovato molti articoli su questo, ma ancora non so come esattamente farlo. Sto cercando di creare il mio motore di blog, ho View for create article (sto usando EF e Code prima) e ora devo compilare il numero di categoria in cui aggiungere l'articolo, ma voglio cambiarlo a dropdownlist con i nomi di categorie. Il mio modello sembra questo:Asp.Net MVC3 - Come creare 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; } 

} 

so che devo utilizzare Enum (o credo), ma io non sono esattamente sicuro di come. Non so quale tutorial da quello che ho trovato sia il migliore per me.


Edit:

Grazie per le vostre risposte, ma ho trovato qualcosa d'altro. Sto cercando in questo modo:

Questo è il mio modello:

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; } 

} 

Questo è il mio controller per creare articolo:

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(); 

    } 
} 

e questo fa parte del mio punto di vista:

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

Ho un problema con NullReferenceExeption ma non so perché. Posso farlo in questo modo? Sembra molto facile per me.

+0

Basta usare quello che si ottiene con l'interfaccia utente di jQuery? – CarneyCode

risposta

20

Il tuo modello sembra abbastanza strano. Contiene proprietà come CategoryID e Category che sembrano ridondanti. Contiene anche una proprietà di raccolta SelectListItem denominata Categories. Quindi, questo è un modello o un modello di vista? Sembra piuttosto incasinato. Supponiamo che sia un modello. In questo caso sarebbe più probabile sembra qualcosa di simile:

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; } 

} 

Ora che il modello è chiaro che potremmo definire un modello di vista che verrà passato alla vista. Un modello di visualizzazione è una classe appositamente progettata per la vista. Quindi, in base a ciò che intendi inserire in questa vista, lo definisci in questo modello di vista. Finora si è parlato solo di un menu a discesa, quindi cerchiamo di farlo:

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

e poi abbiamo un controller:

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); 
    } 
} 

Così il controller utilizza un repository per andare a prendere il modello, lo mappa ad un modello di vista (in questo esempio io uso AutoMapper) e passa il modello visuale alla vista, che si prenderà cura di dimostrarlo:

@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

Credo che le proprietà CategoryID e Category non siano ridondanti. Sta solo dicendo a Entity Framework di nominare la chiave esterna come "IDCategoria", non il predefinito "ID_Categoria" che ha un trattino basso. – rajeemcariazo

4

ho passato con questo come bene e io sono d'accordo all'inizio sembra strano (nella mia spiegazione suppongo che tu voglia selezionare solo una categoria, ma il processo è molto simile per una selezione multipla).

Fondamentalmente è necessario eseguire 3 passi:

1:
avete bisogno di due proprietà sul tuo ViewModel Uno conterrà l'id categoria selezionata (necessario per postback) e l'altro sarà un SelectList con tutti i possibili categorie:

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

    public int CategoryID { get; set; } 

    public SelectList Categories { get; set; } 
} 

2:
anche prima di passare il ViewModel al visualizzazione è necessario inizializzare il SelectList (Best practivce è quello di preparare il più possibile prima di passare un modello nella vista):

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

3:
Nella vista è necessario aggiungere un ListBox per la proprietà CategoryID, ma utilizzando la proprietà Categories anche riempire il ListBox con i valori:

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

questo è tutto! Nell'azione postback del controller verrà impostato il CategoryID. Puoi fare tutto ciò di cui hai bisogno da lì per persistere nel tuo db.