【问题标题】:ASP.Net MVC 3 ViewModel Data AnnotationsASP.Net MVC 3 ViewModel 数据注释
【发布时间】:2012-04-11 01:45:12
【问题描述】:

我正在使用 Entity Framework 4.1 开发一个 ASP.Net MVC 3 Web 应用程序,我对使用数据注释进行表单验证有点困惑。 我总是将 ViewModel 返回给 View,而不是传递实际对象,因为我意识到这是不好的做法。例如:

public class ViewModelTeam
{
    public Team Team { get; set; }
}

我的视图可能会有这样的东西

@model UI.ViewModels.ViewModelTeam

    @Html.HiddenFor(model => model.Team.teamID)


    <div class="editor-label">
        @Html.LabelFor(model => model.Team.description)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Team.description)
        @Html.ValidationMessageFor(model => model.Team.description)
    </div>

为了验证这个视图,我在这样的部分类中创建了数据注释

[MetadataType(typeof(TeamMetaData))]
public partial class Team
{
    public class TeamMetaData
    {
        [DisplayName("Team Name")]
        [Required(ErrorMessage = "Please enter a Team Name")]
        public object description { get; set; }

然后在我的创建控制器中我有这个

[HttpPost]
    public ActionResult Create(Team team)
    {
        if (ModelState.IsValid)
        {
           //Add team and redirect
        }

          //Got this far then errors have happened
          //Add Model State Errors


        ViewModelTeam viewModel = new ViewModelTeam
        {
            Team = team            
        };

        return View(viewModel);
    }

现在,这很好用,但是,我对 ViewModels 和验证的了解越多,似乎应该验证的是 ViewModel,因为归根结底,显示的是 ViewModel在视图中,而不是在对象中。

因此,我将 ViewModel 更改为如下所示

public class ViewModelListItem
{

    public int teamID { get; set; }

    [DisplayName("Item Name")]
    [Required(ErrorMessage = "Please enter a Team Name")]
    public string description { get; set; }

我还将我的创建控制器更改为这个

[HttpPost]
    public ActionResult Create(Team team)
    {
        if (ModelState.IsValid)
        {
           //Add team and redirect
        }

          //Got this far then errors have happened
          //Add Model State Errors

        ViewModelTeam viewModel = new ViewModelTeam();
     viewModel.description = team.description;

        return View(viewModel);
    }

同样,这行得通,但我只是觉得第二种方法有点混乱,或者在第一种方法中效率不高。

我很想听听其他人对此的看法。感谢您的帮助,对于这么长的帖子,我深表歉意。

【问题讨论】:

    标签: asp.net-mvc-3 viewmodel data-annotations partial-classes


    【解决方案1】:

    我总是使用视图模型和AutoMapper 来帮助我简化我的域和视图模型之间的映射。

    查看模型:

    public class TeamViewModel
    {
        [DisplayName("Team Name")]
        [Required(ErrorMessage = "Please enter a Team Name")]
        public string Description { get; set; }
    }
    

    然后是一个常用的模式:

    public class TeamsController: Controller
    {
        public ActionResult Create()
        {
            var model = new TeamViewModel();
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Create(TeamViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
    
            Team team = Mapper.Map<TeamViewModel, Team>(model);
            Repository.DoSomethingWithTeam(team);
    
            return RedirectToAction("Success");
        }
    }
    

    【讨论】:

    • 如果我的 ViewModel 表示一个在创建控制器内具有 30 个属性的对象,如果创建失败,我是否必须将每个属性分配回 ViewModel,即 viewModel.property1 = team.prop1, viewModel.property2 = team.prop2, viewModel.property3 = team.prop3 ... viewModel.property30 = team.prop30 等等。这似乎效率低下,但也许这就是 AutoMapper 的作用?我以前从未使用过。
    • 这很有意义。很好的答案。谢谢。
    • 感谢 Darin Dimitrov 的分享。只是一个问题,所以你只在 ViewModel 上使用 DataAnnoration 而从不在 Model 上?看看这个forums.asp.net/t/1502378.aspx
    • @GibboK,我个人根本不使用数据注释。我改用FluentValidation.NET。根据我正在处理的给定项目的具体情况,我可能没有视图模型和域模型的验证器,或者只有视图模型。至少应该对视图模型进行验证,就领域模型而言,业务规则将决定。
    • 感谢 Darin 的分享,我的项目也会考虑 FluentValidation.NET。
    猜你喜欢
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2011-07-12
    相关资源
    最近更新 更多