2011-02-19 11 views
11

これについて多くの記事が見つかりましたが、これを行うにはどのように正確にはわかりません。私は自分のブログエンジンを作成しようとしています。記事を作成するためのビュー(私はEFとコードを最初に使用しています)を持っていますが、今は記事を追加するカテゴリの番号を記入する必要があります。カテゴリ。私は列挙型を使用する必要があります知っているAsp.Net MVC3 - 動的ドロップダウンリストを作成する方法

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

} 

(または私は思う)が、私は正確にどのように確認していない:私のモデルは、この見えます。私が見つけたチュートリアルが私にとって最高のものであることはわかりません。


編集:

あなたの答えのおかげで、私は何か他のものを見つけました。

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

} 

これは、記事を作成するために私のコントローラである:これは私のモデル

です:私はこれをしようとしています

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

    } 
} 

は、そして、これは私の見解の一部です:

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

NullReferenceExeptionに問題がありますが、理由はわかりません。このようにすることはできますか?それは私のために非常に簡単に見えます。

+0

jQuery UIを使ってすぐに使えるものを使ってください。 – CarneyCode

答えて

20

あなたのモデルはかなり変わっているようです。それは冗長に見えるCategoryIDCategoryのようなプロパティを含んでいます。 CategoriesというSelectListItemコレクションプロパティも含まれています。それで、これはモデルかビューモデルですか?それはかなり台無しに見えます。それがモデルだとしましょう。モデルたちはビューに渡されることになるビューモデルを定義することができます明確であることを今

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

} 

:この場合は、可能性が高く、このようになります。ビューモデルは、ビュー用に特別に設計されたクラスです。したがって、このビューに入れるものに応じて、このビュー・モデルで定義します。これまでのところ、あなたがダウンのみドロップについて話しました、それでは、それをやらせています

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

し、我々は、コントローラを持っている:

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

ので、コントローラは、モデルを取得するためにリポジトリを使用して、それをマップしますビューモデル(この例では、私はAutoMapperを使用)し、それを示すの世話をするビューにビューモデルを渡しに:

@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

CategoryIDとカテゴリのプロパティは重複していないと思います。 Entity Frameworkに、外部キーに「CategoryID」という名前を付けるように指示するだけであり、デフォルトの「Category_ID」にはアンダースコアがありません。 – rajeemcariazo

4

私もこの通過したと私は同意する必要があります最初は奇妙に思えます(私の説明では、1つのカテゴリのみを選択したいと仮定していますが、プロセスは複数の選択に対して非常に似ています)。

1:

は、基本的には、3段階実行する必要がありますあなたはあなたのviewmodel 一つ上の2つのプロパティを必要とする
(ポストバックのために必須)選択したカテゴリIDを保持するが、その他の意志すべてとSelectList可能なカテゴリ:

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

    public int CategoryID { get; set; } 

    public SelectList Categories { get; set; } 
} 

2:
あなたがを初期化する必要があるビューに上のviewmodelを渡す前にも(ベストpractivceは、ビューにモデルを渡す前に、できるだけ多くの準備です):

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

3:ビューで
あなたがCategoryIDプロパティのListBoxを追加する必要がありますが、Categoriesプロパティを使用して、

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

これは値付きのListBoxです。コントローラーのポストバックアクションでは、CategoryIDが設定されます。そこからあなたが必要とすることは何でもでき、DB内のものを維持することができます。

関連する問題