在MVC中使用SelectListItem创建一个通用存储库DropDown

几个月后我回到了这个问题,我已经在下面添加了我目前的最佳答案。

在最初的问题中,我仍然在寻找一种实现通用DropDown的简单方法,但标题与我当时遇到的具体错误更紧密相关。

我修改了标题以更密切地反映答案。 希望这可能对某人有所帮助。


原始问题:

DropDownListFor throws的通用编辑器模板无法转换类型错误

我正在尝试使用从以下post中提取的想法为下拉列表创建通用模板:

将Html DropDownListFor移动到编辑器模板中

我创建了一个DropDownHelper类:

public class DDLOptions { public T Value { get; set; } public IEnumerable Items { get; set; } } 

我从这里修改了控制器:

  public ActionResult Create() { var model = new FilmEditViewModel(); FilmDropDownViewModel films = new FilmDropDownViewModel { Items = _repo.GetSelect(), }; model.filmName = films; return View(model); } 

……对此:

  public ActionResult Create() { var model = new FilmEditViewModel(); DDLOptions films = new DDLOptions { Items = _repo.GetSelect() }; model.filmName = films; return View(model); } 

这会引发以下错误:

 Cannot implicitly convert type 'BootstrapSupport.DDLOptions' to 'FilmStore.ViewModels.FilmDropDownViewModel' 

我也很难解决如何修改编辑器模板以使用修改后的DDLOptions类。

有一种方法可以创建一个通用的DropDown,我已经从StackOverflow上的几个指针和CodeProject上的这篇文章中将它们混合在一起。 关于这是否遵循最佳做法的评论将不胜感激。

我使用AddList和EditList来允许EditList上的选定项和一些基于html类属性的jQuery。 通用EditList创建如下:

楷模

我有一个适合普通模式的DropDown的viewmodel,然后是我正在返回的实体的ViewModel。 注释保存在validation文件中。

DropDown ViewModel

 public class DropDownViewModel { public IEnumerable Items { get; set; } } 

实体ViewModel

 public partial class OrganisationEditViewModel { public int entityID { get; set; } public string entityName { get; set; } public DropDownViewModel entityTypeID { get; set; } public string notes { get; set; } } 

validation

 [MetadataTypeAttribute(typeof(OrganisationEditViewModelMetaData))] public partial class OrganisationEditViewModel { } public class OrganisationEditViewModelMetaData { [Key] [ScaffoldColumn(false)] [HiddenInput(DisplayValue = false)] public int entityID { get; set; } [Required] [Display(Name = "Organisation")] public string entityName { get; set; } [Required] [Display(Name = "Entity Type")] [UIHint("_dropDownEdit")] public DropDownViewModel entityTypeID { get; set; } [Display(Name = "Notes")] public string notes { get; set; } } 

编辑模板

ViewModel上的UIHint注释指向编辑器模板。 我在查找时使用了selected.js ,因此是html属性。

 @model WhatWorks.ViewModels.DropDownViewModel @Html.DropDownList("", Model.Items, new { @class = "chosen chosenLookup" }) 

调节器

控制器查询当前实体以获取EditList的选定字符串。 DropDown是从存储库中的GetEditList函数调用的。 然后通过Automapper ( GetUpdate(id) ) 映射 ViewModel。

 public ActionResult Edit(int id = 0) { var query = _repo.GetByID(id); string selected = query.tEntityType.entityTypeID.ToString(); DropDownViewModel entityType = new DropDownViewModel { Items = _repo.GetEditList("entityType", "entityTypeID", selected) }; OrganisationEditViewModel a = GetUpdate(id); a.entityTypeID = entityType; if (a == null) { return HttpNotFound(); } return View(a); } 

知识库

通用DropDown存储库方法从调用类型获取IEnumerable数据集(在本例中为tEntityType )。 return方法将所有内容转换为字符串并检查所选项。

 //generic Edit dropdown public IEnumerable GetEditList(string text, string value, string selected) where O : class { IEnumerable result = context.Set(); var query = from e in result select new { Value = e.GetType().GetProperty(value).GetValue(e, null), Text = e.GetType().GetProperty(text).GetValue(e, null) }; return query.AsEnumerable() .Select(s => new SelectListItem { Value = s.Value.ToString(), Text = s.Text.ToString(), Selected = (selected == s.Value.ToString() ? true : false) }); } 

视图

最后,视图通过标准Html.Editor呈现DropDown,它从validation文件上的UIHint注释中获取编辑器模板。