使用AutoMapper / AutoMapViewResult时如何获取下拉列表的数据到viewmodel [英] How to get data for a dropdownlist into viewmodel when using AutoMapper/AutoMapViewResult

查看:129
本文介绍了使用AutoMapper / AutoMapViewResult时如何获取下拉列表的数据到viewmodel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读 ASP.NET MVC 2操作并观看 Jimmy Bogard来自MvcConf的演讲(都非常推荐!),我开始实现他们的一些想法。



他们做的很酷的事情之一不仅是使用AutoMapper将实体映射到一些viewmodel,而且可以使用AutoMapViewResult自动执行:

  public class EventsController:BaseController 
{
public ActionResult Show(Event id)// EntityModelBinder从存储库获取事件
{
返回AutoMapView< EventsShowModel>(id); // AutoMapView&T;(Model)是BaseController上的一个帮助方法,它调用AutoMapViewResult< T>(...)
}
}

//不完全你会在书中找到,但它也可以:-)
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));
}
}

这一切都很好,但现在有一个code>编辑动作与其 EventsEditModel

  public class EventsEditModel 
{
// ...一些属性...
public int LocationId {get;组; }
public IList< SelectListItem>地点{get;组;


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

现在(最后)



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



请记住,我想使用 AutoMapViewResult 和很多不同的实体视图模型组合。



更新: / p>

我去了Necros的想法,并创建了一个自定义属性。您可以在我的博客上查看代码并将其下载 ASP.NET MVC:使用属性将选择列表的数据加载到编辑模型中

解决方案

当我需要这个时,我还没有看到这一点(因为我看到了这个话题),但是我有一个可能的解决方案。我认为创建一个属性是有效的,指定需要加载该属性。我将从抽象类开始:

  public abstract class LoadDataAttribute:Attribute 
{
public Type Type {get;组;

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

public abstract object LoadData();
}

然后为要加载的每种类型创建特定版本(您的案例中的位置)

  public class LoadLocationsAttribute:LoadDataAttribute 
{
public LoadLocationsAttribute():base(typeof(IList& SelectListItem>))

public override object LoadData()
{
//获取位置并返回IList< SelectListItem>
}
}

在您的 ExecuteResult AutoMappViewResult 你会发现所有的属性与 LoadDataAttribute ,调用 LoadData ),将其转换为属性中指定的类型并将其分配给该属性。



如果您只想以这种方式加载选择列表,您只需返回 IList< SelectListItem> 而不是对象,并保存自己一些转换的麻烦。 >

您的视图模型显然会使用该属性。

  public class EventsEditModel 
{
// ...一些属性...
public int LocationId {get;组; }

[LoadLocations]
public IList< SelectListItem>地点{get;组; }
}


After reading ASP.NET MVC 2 in Action and watching Jimmy Bogard's presentation from MvcConf (both highly recommended!), I began to implement some of their ideas.

One of the cool things they do, is not only to use AutoMapper to map your entities to some viewmodel, but automate this with an 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));
    }
}

This all works great, but now there's a Edit action with its EventsEditModel:

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

And now (finally) the question:

What do you think, is the best way to get the locations from some sort of data source such as a repository to the EventsEditModel's Locations property?

Keep in mind, that I want to use the AutoMapViewResult and a lot of different entity-viewmodel combinations.

Update:

I went with Necros' idea and created a custom attribute. You can look at the code and download it on my blog ASP.NET MVC: Loading data for select lists into edit model using attributes.

解决方案

I haven't gotten to the point (since I saw the talk) when I needed this, but I have a possible solution for this in mind. I think it would work to create an attribute, specifying that this property needs to be loaded. I would start with an abstract class:

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

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

    public abstract object LoadData();
}

Then create specific version for each type you want to load (Locations in your case)

public class LoadLocationsAttribute : LoadDataAttribute
{
    public LoadLocationsAttribute() : base(typeof(IList<SelectListItem>))

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

In your ExecuteResult of AutoMappViewResult you would find all properties with LoadDataAttribute, call LoadData(), cast it to type specified in the attribute and assign it to the property.

I case you just want to load select lists this way, you can just return IList<SelectListItem> instead of object, and save yourself some trouble with casting.

Your view model would the obviously use the attribute.

public class EventsEditModel
{
    // ... some properties ...
    public int LocationId { get; set; }

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

这篇关于使用AutoMapper / AutoMapViewResult时如何获取下拉列表的数据到viewmodel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆