ASP.Net MVC 3 视图模型数据注解

18

我正在开发一个使用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; }

然后在我的create Controller中,我有这个代码

[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才是在View中显示的对象,而不是原始对象。

因此,我将我的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);
    }

再次强调,这个方法可以工作,但我感觉第二种方式有些混乱或不如第一种方式高效。

我很想听听其他人的想法。谢谢您的帮助,对于这样一个长篇我表示歉意。

1个回答

12

我经常使用视图模型和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");
    }
}

感谢Darin Dimitrov的分享。只是一个问题,所以您只在ViewModel上使用DataAnnoration而从不在Model上使用吗?看一下这个http://forums.asp.net/t/1502378.aspx - GibboK
1
@GibboK,就我个人而言,我根本不使用数据注释。相反,我使用FluentValidation.NET。根据我所工作的具体项目的特定情况,我可能会在视图模型和领域模型上都有验证器,也可能只在视图模型上有验证器。至少应该在视图模型上进行验证,至于领域模型,则要根据业务规则来确定。 - Darin Dimitrov
感谢Darin的分享,我也会考虑在我的项目中使用FluentValidation.NET。 - GibboK
如果您直接注解您的模型,您就会在模型和用户界面之间创建耦合。我想我说得对。这就是为什么Darin使用ViewModel来实现此目的。 - Doug Chamberlain
我是指显示属性注释。 - Doug Chamberlain
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接