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

时间:2013-09-25 13:15:04

标签: c# asp.net-mvc generics repository mvc-editor-templates

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

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

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


原始问题:

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

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

Move Html DropDownListFor into Editor Template

我创建了一个DropDownHelper类:

public class DDLOptions<T>
{
    public T Value { get; set; }
    public IEnumerable<SelectListItem> 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<FilmDropDownViewModel> films
            = new DDLOptions<FilmDropDownViewModel>
            {
                Items = _repo.GetSelect()
            };

        model.filmName = films;           
        return View(model);
    }

这会引发以下错误:

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

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

1 个答案:

答案 0 :(得分:1)

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

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

模型

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

DropDown ViewModel

public class DropDownViewModel
{
    public IEnumerable<SelectListItem> 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; }
}

验证

[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注释指向编辑器模板。我在查询中使用chosen.js,因此是html属性。

@model WhatWorks.ViewModels.DropDownViewModel

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

控制器

控制器查询当前实体以获取EditList的选定字符串。 DropDown是从存储库中的GetEditList<O>函数调用的。然后通过AutomapperGetUpdate(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<tEntityType>("entityType", "entityTypeID", selected)
    };

    OrganisationEditViewModel a = GetUpdate(id);
    a.entityTypeID = entityType;

    if (a == null)
    {
        return HttpNotFound();
    }
    return View(a);
}

存储库

通用DropDown存储库方法从调用类型IEnumerable(在这种情况下为<O>)中获取tEntityType个数据集。 return方法将所有内容转换为字符串并检查所选项目。

//generic Edit dropdown
    public IEnumerable<SelectListItem> GetEditList<O>(string text, string value, string selected) 
                                                        where O : class
    {
        IEnumerable<O> result = context.Set<O>();
        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,该标准从验证文件上的UIHint注释中选取编辑器模板。