C# 如何在asp.net mvc 5中通过视图创建/编辑模型
我有一个关于我的模型的问题,你可以在下图中看到 如你们所见,我得到了3个实体,它们之间有1:n和m:n的关系 我希望我可以通过web界面编辑这些模型。因此,我构建了这三个模型(使用实体框架添加控制器),得到了C# 如何在asp.net mvc 5中通过视图创建/编辑模型,c#,asp.net,asp.net-mvc,entity-framework,scaffolding,C#,Asp.net,Asp.net Mvc,Entity Framework,Scaffolding,我有一个关于我的模型的问题,你可以在下图中看到 如你们所见,我得到了3个实体,它们之间有1:n和m:n的关系 我希望我可以通过web界面编辑这些模型。因此,我构建了这三个模型(使用实体框架添加控制器),得到了edit/delete/create/视图,当然每个实体都有一个控制器 但是VS没有为关系自动创建输入/字段,所以我想手动实现它们。在我想这样做之前,是否有一种更简单的方法来实现/构建这个模型,这样我甚至可以编辑关系(复选框或(多)选择是最好的)? 提前谢谢 对于一个或多个,您可以在合作伙
edit/delete/create/
视图,当然每个实体都有一个控制器
但是VS没有为关系自动创建输入/字段,所以我想手动实现它们。在我想这样做之前,是否有一种更简单的方法来实现/构建这个模型,这样我甚至可以编辑关系(复选框或(多)选择是最好的)?
提前谢谢 对于一个或多个,您可以在合作伙伴视图中为Tip使用DropDownList(请参阅。许多可以通过ViewModels和JavaScript框架(如Knockout)来处理。不,这里的框架是故意不附带的,因为有许多不同的方法可以处理这个问题。也许您只想从选择列表中进行选择?也许您想要复选框,或者,您想在对于最后一个,您是想一次发布所有内容还是使用AJAX 因此,框架没有为您选择,而是将决策权留给您,因为只有您知道应用程序应该如何构建。不管怎样,依赖框架往往会让您感到痛苦。它们只在最基本和最理想的场景中工作,应用程序需求何时是基本或理想的?现在我甚至都不关心它们,我更喜欢手动创建我的控制器/视图。它最终比处理脚手架和撤销所有不适用的东西都要快 因此,由于您正在寻找选择框(单选或多选),首先,我建议为您的实体创建视图模型
public class TipViewModel
{
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[Required]
public int? SelectedPartnerId { get; set; }
public IEnumerable<SelectListItem> PartnerChoices { get; set;}
[Required]
public int? SelectedBookId { get; set; }
public IEnumerable<SelectListItem> BookChoices { get; set; }
}
我已经提取了填充这些选择列表的代码,因为该代码将在整个控制器中多次使用。此外,我在书籍的文本值上使用string.Format
,只是为了表明您可以对选择列表项的文本执行任何操作。此外,上面的代码将用于cr很明显,执行eate操作。执行编辑类似,但略有不同:
public ActionResult Edit(int id)
{
var tip = db.Tips.Find(id);
if (tip == null)
{
return new HttpNotFoundResult();
}
var model = new TipViewModel
{
Name = tip.Name,
Description = tip.Description,
SelectedPartnerId = tip.Partner != null ? tip.Partner.Id : new int?(),
SelectedBookId = tip.Book != null ? tip.Book.Id : new int?()
}
PopulateChoices(model);
return View(model);
}
主要区别在于,您显然正在处理一个现有实例,因此需要从数据库中提取该实例。然后,您只需要将实体中的数据映射到视图模型上。同样,由于您没有明确的外键属性,因此您必须做一些额外的工作,以获得当前选择的合作伙伴
/Book
values,否则您可以直接复制外键属性的值。另外,在这里,我只是在手动映射,但有第三方库可以简化此任务(请参阅:)
这样,您就可以实现视图。一切都将与您直接使用实体时的工作方式相同,您只需进行一些修改。首先,您需要更改视图的模型声明:
@model Namespace.To.TipViewModel
然后,添加两个相关属性的选择列表:
@Html.DropDownListFor(m => m.SelectedPartnerId, Model.PartnerChoices)
...
@Html.DropDownListFor(m => m.SelectedBookId, Model.BookChoices)
有趣的事情发生在操作的后期版本中。大多数代码将与GET版本保持一致,但现在您将有一个if(ModelState.IsValid)
块:
[HttpPost]
public ActionResult Create(TipViewModel model)
{
if (ModelState.IsValid)
{
// map the data from model to your entity
var tip = new Tip
{
Name = model.Name,
Description = model.Description,
Partner = db.Partners.Find(model.SelectedPartnerId),
Book = db.Books.Find(model.SelectedBookId)
}
db.Tips.Add(tip);
db.SaveChanges();
return RedirectToAction("Index");
}
// Form has errors, repopulate choices and redisplay form
PopulateChoices(model);
return View(model);
}
编辑版本也是类似的,只是要映射到现有实例上,例如:
tip.Name = model.Name;
tip.Description = model.Description;
tip.Partner = db.Partners.Find(model.SelectedPartnerId);
tip.Book = db.Books.Find(model.SelectedBookId);
这就是引用属性的全部内容。在您的问题中,您的实体上实际上没有任何M2M甚至一对多的内容。所有内容都是一对一的,但如果您确实有集合属性,则需要稍微不同地处理它。您仍然需要视图模型上的属性来保存选定的值和e现有选择:
public List<int> SelectedFooIds { get; set; }
public IEnumerable<SelectListItem> FooChoices { get; set; }
并且,您需要对编辑操作的GET和POST版本进行更改。对于GET,您需要将集合属性压缩为ID列表:
var model = new TipViewModel
{
...
SelectedFooIds = tip.Foos.Select(m => m.Id).ToList(),
}
在编辑版本中,您可以设置新的选定项目:
tip.Foos = db.Foos.Where(m => model.SelectedFooIds.Contains(m.Id);
最后,在视图中,您可以使用ListBoxFor
而不是DropDownListFor
来启用multiselect:
@Html.ListBoxFor(m => m.SelectedFooIds, Model.FooChoices)
+1-否决票被否决
tip.Foos = db.Foos.Where(m => model.SelectedFooIds.Contains(m.Id);
@Html.ListBoxFor(m => m.SelectedFooIds, Model.FooChoices)