Create a generic repository DropDown with SelectListItem in MVC

前端 未结 1 700
渐次进展
渐次进展 2021-01-28 11:26

Having returned to this problem after a few months I\'ve added my current best answer below.

In the original question I was still looking for a simple way to achieve a g

1条回答
  •  春和景丽
    2021-01-28 12:25

    There is a way to create a generic DropDown which I've mangled together from a few pointers on StackOverflow and this article on CodeProject. Comments on whether this follows best practice would be appreciated.

    I use both an AddList and an EditList to allow for a selected item on the EditList and some jQuery based on html class attributes. The generic EditList is created as follows:

    Models

    I have a viewmodel for any DropDown that fits with the generic pattern and then a ViewModel for the entity I'm returning. Annotations are held in a validation file.

    DropDown ViewModel

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

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

    Editor Template

    The UIHint annotation on the ViewModel points to an Editor Template. I'm using chosen.js on my lookups, hence the html attributes.

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

    Controller

    The controller queries the current entity to get the selected string for the EditList. The DropDown is called from the GetEditList function in the repository. The ViewModel is then mapped via Automapper (GetUpdate(id)).

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

    Repository

    The generic DropDown repository method gets an IEnumerable set of data from the calling type (tEntityType in this case). The return method converts everything into strings and checks for the selected item.

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

    View

    Finally, the view renders the DropDown via a standard Html.Editor which picks up the Editor Template from the UIHint annotation on the validation file.

    0 讨论(0)
提交回复
热议问题