从使用Model转换为ViewModel

时间:2012-10-10 09:10:19

标签: asp.net-mvc ef-code-first

我有一个列出所有用户的索引页面。这在Users控制器中有以下内容 -

 public ViewResult Index()
        {
            return View(userRepository.AllIncluding(user => user.Roles));
        }

然后视图以

开头
@model IEnumerable<TRS.Models.User>

然后使用

 @foreach (var item in Model) {

遍历我模型中的所有用户。

我现在需要将我的模型更改为包含User模型和扩展UserDetails模型的ViewModel。

我已将我的索引视图更改为使用视图模型 -

@model IEnumerable<TRS.ViewModels.RegisterViewModel>

但我不知道如何在控制器中填充ViewModel -

public ViewResult Index()
        {

            var viewModel = new RegisterViewModel
            {
                UserName = "???"
                FirstName = "???"
                LastName = "???"
            };

            return View(viewModel);
        }

我假设我需要创建一个视图模型的实例,然后将其传递给视图。但我不明白如何针对每个项目获取数据。我显然需要在这里获取所有用户的所有数据,然后在我的视图中循环遍历它们。任何想法我应该在上面的控制器?什么应该取代“???”用它来填充viewModel的所有数据?或者这是错误的做法?

由于

编辑 - 添加的模型 -

public class User
    {
        [Key]
        public string UserName { get; set; }

        public virtual ICollection<Role> Roles { get; set; }
        public virtual UserDetails UserDetails { get; set; }
}


 public class UserDetails
    {

        [Key]
        public string UserName { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }

        [Required]
        public virtual User User { get; set; }
}

编辑 - 从视图 -

<td>
                @foreach (Role role in item.Roles){
                @role.RoleName <br />
    }</td> 

4 个答案:

答案 0 :(得分:1)

public ActionResult Index()
{
    var usersVm = userRepository
        .AllIncluding(user => user.Roles)
        .Select(user => new RegisterViewModel
        {
            UserName = user.UserName
            FirstName = user.UserDetails.FirstName
            LastName = user.UserDetails.LastName
        });
    return View(usersVm);
}

答案 1 :(得分:0)

Automapper就是为此而创建的。我强烈推荐它。

阅读wiki的getting started部分。

配置完成后,您的控制器代码将如下所示:

List<RegisterViewModel> registrants = 
                  Mapper.Map<List<User>, List<RegisterViewModel>>(users);

虽然您可能想要考虑一个包含注册人列表的视图模型,但这取决于您。

答案 2 :(得分:0)

从您的问题中不清楚UserDetails的样子。

你不应该使用IEnumerable&lt; RegisterViewModel&gt;在你看来。 RegisterViewModel应该是视图中所需的所有内容的容器:

    public ViewResult Index()
    {
        var usersDetails = GetUserDetails(userRepository.AllIncluding(user => user.Roles));

        var viewModel = new RegisterViewModel
        {
            UserDetails = usersDetails.ToList(),
            SomeMoreDataRequiredByTheView= "1"
        };

        return View(viewModel);
    }

   //you can use automapper to do this dirty job.
   private IEnumerable<UserDetails> GetUserDetails(IEnumerable<User> users)
   {
       foreach(var user in users)
       {
           yield return new UserDetails()
           {
               FullName = user.FirstName + " " + user.LastName,
               // Other stuff you want

           };
       }
   }

答案 3 :(得分:0)

您的viewModel

    Public Class RegisterViewModel
   {
      Public IEnumerable<TRS.Models.User> AllUsers {get;set;}
      Public IEnumerable<TRS.Models.UserDetails> UserDetails {get;set;}
   } 

然后在您的控制器中

public ViewResult Index()
{

    var viewModel = new RegisterViewModel
    {
        AllUsers = userRepository.AllIncluding(user => user.Roles).ToList()
    };

    var DetailList = new list<TRS.Models.UserDetails>();
    foreach(var user in viewModel.AllUsers)
    {
        DetailList.add(new userDetails
       {
          name = user.Name,
          age = user.age, 
          ....
       }
    }

    viewModel.UserDetails = DetailList;

    return View(viewModel);
}