【问题标题】:How to do Lists in a view model? + dataannotations如何在视图模型中做列表? + 数据注释
【发布时间】:2011-06-18 05:02:12
【问题描述】:

我正在使用 asp.net mvc 3、数据注释和自动映射器。

一旦属性通过验证,我希望在视图模型中对属性进行所有注释,我使用自动映射器将其映射回我的域对象。

我有一个视图模型,它具有我想要收集的属性,因为我想从它们生成一个表。以后我也想用它们作为表单来向这个表中添加行。

那我该怎么办?我如何获取这些属性并收集它们?

public class UserViewModel()
{
    [Required()]
    public string UserName = {get; set;}
    [Required()]
    public string FirstName = {get; set;}
    [Required()]
    public string LastName = {get; set;}
}

我想使用这些属性来生成我的表格并用于表格。

我唯一能想到的就是这样做

   public class AddUserViewModel()
    {
        [Required()]
        public string UserName = {get; set;}
        [Required()]
        public string FirstName = {get; set;}
        [Required()]
        public string LastName = {get; set;}
    }

   public class UserViewModel()
   {
       public List<User> Users {get; set;}
       public AddUserViewModel {get; set;}

       public UserViewModel()
       {
           Users = new List<Users>();
       }
   }

所以基本上我将它作为一个单独的视图模型包含在另一个包含用户列表(我的域模型)的视图模型中

这样我就使用我的域模型来生成表和我的 AddUserViewModel 来添加用户。

似乎有点多余,所以我不确定是否有更好的方法。

编辑

我有这样的事情

 var viewModel = new UserViewModel();
 List<Users> users=  UserService.GetAllUsers();
 viewModel = Mapper.Map<Users, UserViewModel>(users);
 return View("Index", viewModel);

我也试过

var viewModel = new UserViewModel();
 List<Users> users=  UserService.GetAllUsers();
 viewModel.AddUserViewModel = Mapper.Map<Users, AddUserViewModel>(users);
 return View("Index", viewModel);

编辑 2

我有这个并且它可以编译但是我得到这个错误

        SomeViewModel viewModel = new SomeViewModel ();       
        List<User> users=  userService.GetAllUsers();
        viewModel.UserViewModel = Mapper.Map<List<User>, List<UserViewModel>>(users);
        return View("Index", viewModel);


Trying to map Domain.User to ViewModels.UserViewModel.
Missing type map configuration or unsupported mapping.
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.

【问题讨论】:

  • 我完全不明白你的问题,也不明白你想要达到的目标。
  • @Darin Dimitrov - 是的,这是一个错字。现在已经纠正了。我试图弄清楚如何在视图模型中继续使用数据注释,但也可能返回我的域对象列表,而无需重复代码两次。现在,Users 对象中的所有内容基本上都是 AddUserViewModel() 中的内容的副本。我可以将注释放在域对象中,但我不想这样做。

标签: c# asp.net-mvc asp.net-mvc-3 viewmodel


【解决方案1】:

为什么要在视图模型中返回域对象列表?这不是视图模型应该是的。视图模型应该只引用其他视图模型。所以你有一个很好的UserViewModel 代表一个用户。现在您需要在您的视图中与多个用户一起工作,因此您可以传递一个IEnumerable&lt;UserViewModel&gt;,或者如果您需要一些其他属性,您可以为此设计一个视图模型:

public class UserViewModel
{
    [Required]
    public string UserName = { get; set; }
    [Required]
    public string FirstName = { get; set; }
    [Required]
    public string LastName = { get; set; }
}

public class SomeViewModel
{
    public List<UserViewModel> Users { get; set; }
    public string SomeOtherProperty { get; set; }
}

现在您的控制器操作可能如下所示:

public ActionResult Foo()
{
    SomeModel model = _repository.GetModel();
    SomeViewModel viewModel = Mapper.Map<SomeModel, SomeViewModel>(model);
    return View(viewModel);
}

现在在您的视图中,您可以简单地使用此 Users 属性 (Html.DisplayFor(x =&gt; x.Users)) 的显示模板来显示它们的列表。


更新:

在看到您的更新后,这里是如何按照良好做法进行操作:

public ActionResult Foo()
{
    IEnumerable<Users> users = _repository.GetUsers();
    IEnumerable<UserViewModel> usersViewModel = Mapper
        .Map<IEnumerable<Users>, IEnumerable<UserViewModel>>(users);
    return View(usersViewModel);
}

我还在sample project 中使用了AutoMap 属性,这可以将您的代码简化为:

[AutoMap(typeof(IEnumerable<Users>), typeof(IEnumerable<UserViewModel>))]
public ActionResult Foo()
{
    IEnumerable<Users> users = _repository.GetUsers();
    return View(users);
}

此属性将在控制器操作之后和视图渲染之前自动运行,并使用 AutoMapper 将模型替换为相应的视图模型。

【讨论】:

  • @Darin Dimitrov - 嗯,我认为拥有一组视图模型很糟糕。很难确定什么是正确的方法,就像在本教程中stephenwalther.com/blog/archive/2009/04/13/… 他正在做我所拥有的一样
  • @chobo2,不,拥有视图模型集合一点也不坏。您所指的示例使用IEnumerable&lt;Product&gt;,这正是我在回答的第一部分中向您建议的:IEnumerable&lt;UserViewModel&gt;。在此示例中,Product 应被视为视图模型。此外,您应该避免在视图中编写 foreach 循环。您应该使用显示/编辑器模板。它将使您的代码更加简洁。因此,您可以轻松地将博客文章中显示的 foreach 替换为视图中的一行:Html.DisplayFor(x =&gt; x.Products)
  • @Darin Dimitrov - 但它不是他的域对象吗?我的意思是,你可以考虑我对我说的我的 ViewModel(User)。我猜显示/编辑器模板是一个全新的问题,因为我总是使用 foreach。
  • @chobo2,这篇博文被简化得如此之多,以至于您实际上无法说出Product 是域还是视图模型。他不使用任何存储库来获取它:它在控制器操作中被硬编码,因此这不可能是真实世界的示例。博客文章的作者在这里试图说明的不是域与视图模型,而是 ViewData 与强类型视图。对我来说,传递给视图的所有内容都应该是视图模型。
  • @Darin Dimitrov - 好吧,这是有道理的。我想知道我是否要生成一个表并需要重复行显示模板如何消除 foreach 循环?
猜你喜欢
  • 2013-05-27
  • 2017-12-07
  • 1970-01-01
  • 2011-05-26
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
相关资源
最近更新 更多