私はこれに関する多くの記事を見つけましたが、それでもこれを正確に行う方法がわかりません。独自のブログエンジンを作成しようとしています。記事を作成するためのビューがあり(最初にEFとコードを使用しています)、記事を追加するカテゴリの番号を入力する必要がありますが、名前をドロップダウンリストに変更したいと思います。カテゴリ。私のモデルはこれに見えます:
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に問題がありますが、理由がわかりません。このようにできますか?それは私にはとても簡単に見えます。
あなたのモデルはかなり奇妙に見えます。冗長に見えるCategoryID
やCategory
などのプロパティが含まれています。また、SelectListItem
と呼ばれるCategories
コレクションプロパティも含まれています。それで、これはモデルですか、それともビューモデルですか?それはかなりめちゃくちゃに見えます。それがモデルだとしましょう。この場合、次のようになります。
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つのカテゴリのみを選択することを想定していますが、プロセスは複数選択の場合と非常に似ています)。
基本的にあなたは実行する必要がありますステップ:
1:
ビューモデルに2つのプロパティが必要です。1つは選択したカテゴリID(ポストバックに必要)を保持し、もう1つはすべての可能なカテゴリを含むSelectList
を保持します。
public class Article
{
public int ArticleID { get; set; }
public int CategoryID { get; set; }
public SelectList Categories { get; set; }
}
2:
また、ビューモデルをビューに渡す前に、SelectList
を初期化する必要があります(モデルをビューに渡す前に、できるだけ多くの準備をするのが最善の方法です)。
new SelectList(allCategories, "CategoryID", "Name", selectedCategoryID)
3:
ビューで、ListBox
プロパティにCategoryID
を追加する必要がありますが、Categories
プロパティを使用する場合もListBox
に値を入力します:
@Html.ListBoxFor(model => model.CategoryID , Model.Categories)
それでおしまい!コントローラのポストバックアクションでは、CategoryIDが設定されます。データベースに物事を永続化するために、そこから必要なことは何でもできます。