asp.net-mvc - 使用AutoMapper/AutoMapViewResult时如何将下拉列表的数据获取到ViewModel中

标签 asp.net-mvc drop-down-menu viewmodel automapper

阅读ASP.NET MVC 2 in Action和观看Jimmy Bogard's presentation from MvcConf(强烈推荐!)之后,我开始实现他们的一些想法。

他们要做的很酷的事情之一,不仅是使用AutoMapper将您的实体映射到某些 View 模型,还可以使用AutoMapViewResult将其自动化:

public class EventsController : BaseController
{
    public ActionResult Show(Event id) // EntityModelBinder gets Event from repository
    {
        return AutoMapView<EventsShowModel>(id); // AutoMapView<T>(model) is a helper method on the BaseController, that calls AutoMapViewResult<T>(...)
    }
}

// not exactly what you'll find in the book, but it also works :-)
public class AutoMapViewResult<TDestination> : ViewResult
{
    public AutoMapViewResult(string viewName, string masterName, object model)
    {
        ViewName = viewName;
        MasterName = masterName;

        ViewData.Model = Mapper.Map(model, model.GetType(), typeof(TDestination));
    }
}

这一切都很好,但是现在有了EditEventsEditModel Action :
public class EventsEditModel
{
    // ... some properties ...
    public int LocationId { get; set; }
    public IList<SelectListItem> Locations { get; set; }
}

public class EventsController : BaseController
{
    public ActionResult Edit(Event id)
    {
        return AutoMapView<EventsEditModel>(id); 
    }
}

现在(最后)是一个问题:

您认为,从某种数据源(例如存储库)到EventsEditModelLocations属性获取位置的最佳方法是什么?

请记住,我要使用AutoMapViewResult和许多不同的entity-viewmodel组合。

更新:

我接受了Necros的想法,并创建了一个自定义属性。您可以查看代码并将其下载到我的博客ASP.NET MVC: Loading data for select lists into edit model using attributes上。

最佳答案

(自从我看了这篇演讲之后)我还没有到达需要的时候,但是我想到了一个可能的解决方案。我认为创建一个属性,指定需要加载此属性将是可行的。我将从一个抽象类开始:

public abstract class LoadDataAttribute : Attribute
{
    public Type Type { get; set; }

    protected LoadDataAttribute(Type type)
    {
        Type = type;
    }

    public abstract object LoadData();
}

然后为要加载的每种类型创建特定的版本(您所用的位置)
public class LoadLocationsAttribute : LoadDataAttribute
{
    public LoadLocationsAttribute() : base(typeof(IList<SelectListItem>))

    public override object LoadData()
    {
        // get locations and return IList<SelectListItem>
    }
}

ExecuteResultAutoMappViewResult中,您会找到所有带有LoadDataAttribute的属性,调用LoadData(),将其强制转换为属性中指定的类型,并将其分配给该属性。

如果您只是想以这种方式加载选择列表,则可以只返回IList<SelectListItem>而不是object,从而省去了一些转换方面的麻烦。

您的 View 模型显然会使用该属性。
public class EventsEditModel
{
    // ... some properties ...
    public int LocationId { get; set; }

    [LoadLocations]
    public IList<SelectListItem> Locations { get; set; }
}

关于asp.net-mvc - 使用AutoMapper/AutoMapViewResult时如何将下拉列表的数据获取到ViewModel中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3507466/

相关文章:

c# - 在 ASP.NET MVC 4 中显示日期时间

asp.net-mvc - 将枚举参数从 Ajax Jquery 传递到 MVC Web api

html - Bootstrap水平下拉菜单?

jquery - Bootstrap 下拉菜单 : events for the 'navbar-toggle' ?

mvvm - 如何使用 Hilt (Jetpack Compose) 将 ViewModel 注入(inject)可组合函数

c# - AutoComplete 控件调用具有空值的 Controller

c# - 对 ASP.NET MVC4 中的 return View() 方法感到困惑

html - 下拉悬停在 IE9 中不保持打开状态

wpf - WPF在 View 中更改ViewModel属性

wpf - 用于复合绑定(bind)的 ViewModel 与 ValueConverter