用MVC做信息管理系统的时候,通常会遇到“添加”和“编辑”,例如,添加一个用户,编辑一个用户,添加用户的时候,需要验证用户名没有被使用,而编辑一个用户的时候则不需要这个验证。除了这个之外,别的字段的验证都基本没什么差别,例如用户生日啊,地址啊,其它乱七八糟的描述之类。如果我们为此创建了两个Model(一个AddUser,一个EditUser),两个View的话(一个AddUser一个EditUser),就会产生大量重复代码。关于重复代码的危害,我在此就不多说了。
立即想到的解决方法是创建一个UserBase的基类,里面是AddUser和EditUser的共同内容,AddUser和EditUser都从UserBase派生下来,这样能削除掉Model的重复代码,但是View的重复代码怎么办呢?一样还是得创建两个View啊,作为强类型的View,不能同时是AddUser和EditUser的。
关于怎么做,我在asp.net发了一个帖子问: http://forums.asp.net/t/1799937.aspx/1?Help+how+to+avoid+repeated+code+
我也考虑了很多方法,最后敲定了下面这个方法,也许别的方法也行,但我下面提供的这个方法副作用最小。
一个Model:
public class User { private const string NOT_NULL = "不可为空"; private const string USERNAME_REGULAR = "用户名必须由字母、数字或下划线组成,3-20个字符"; //------The model type condition ------ public string ModelType { get; set; } //"add" or "edit" //-----------Add------------ [RequiredIf("ModelType", "add", ErrorMessage = NOT_NULL)] [RegularExpression(@"^[0-9a-zA-Z_]{3,20}$", ErrorMessage = USERNAME_REGULAR)] [Remote("ValidateUserName","Home",ErrorMessage="用户已经存在")] public string UserName_Add{get;set;} //-----------Edit----------- [RequiredIf("ModelType", "edit", ErrorMessage = NOT_NULL)] [RegularExpression(@"^[0-9a-zA-Z_]{3,20}$", ErrorMessage = USERNAME_REGULAR)] public string UserName_Edit { get; set; } //----------Comm data------- [Range(1, 100)] public int Age { get; set; } public string Descriptions { get; set; } }
一个View:
@model MvcCombinedCode.Models.User @{ ViewBag.Title = "AddUser"; Layout = "~/Views/Shared/_Layout.cshtml"; } @using (Html.BeginForm()) { @Html.HiddenFor(model=>model.ModelType) if (Model.ModelType == "add") { <div>增加新用户</div> <div>输入用户名</div> <div>@Html.TextBoxFor(model => model.UserName_Add) @Html.ValidationMessageFor(model => model.UserName_Add)</div> } else { <div>编辑用户</div> <div>当前用户</div> <div>@Model.UserName_Edit @Html.HiddenFor(model => model.UserName_Edit)</div> } <div>年龄</div> <div>@Html.TextBoxFor(model => model.Age) @Html.ValidationMessageFor(model => model.Age)</div> <div>描述</div> <div>@Html.TextAreaFor(model => model.Descriptions)</div> <div><input type="submit" /></div> }
大家已经注意到Model上的[RequiredIf]标签了,这是条件需求,例如“[RequiredIf("ModelType", "add", ErrorMessage = NOT_NULL)]”的意思是:当“ModelType”等于“add”的时候,UserName_Add才“不可为空”,如果UserName_Add为空,那么就不需要其它验证了。关于RequiredIf,大家可以到参考这篇文章:
http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx
我直接使用了它提供的代码。下面是我写的demo,VS2010+MVC3调试通过。