在实体类中使用RemoteAttribute特性可以非常方便的在界面异步进行验证数据的有效性。
该类可以异步调用Action来进行数据有效性判断,例如:
Model 中代码片段如下:
1 [Display(AutoGenerateField=true,Name="标题")] 2 [Required(AllowEmptyStrings=false,ErrorMessage="请填写标题")] 3 [StringLength(200,ErrorMessage="标题字符个数在2-200个之间!",MinimumLength=2)] 4 [Remote("GetFaultByTitle", "FaultManual", ErrorMessage = "该标题已存在!", HttpMethod = "post")] 5 public string Title { get; set; }
Remote特性,可以指定将来异步请求的Action名称,Controller名称,错误消息,并且可以指定http请求方式。(看到很多人写的博文上说,只能使用get情况,这里特意使用post请求。)
Controller 中代码片段如下:
1 public ActionResult GetFaultByTitle(string title) 2 { 3 int count = db.FTM_FaultContents.Where(c => c.Title == title).Count(); 4 return Json(count == 0); 5 }
View 中代码片段如下:
1 <div class="editor-field"> 2 @Html.DropDownListFor(model => model.Type.FTM_TypesId, ViewData["ftm_Type"] as SelectList) 3 @Html.ValidationMessageFor(model => model.Title) 4 </div>
该方式能够自动的验证这个Title的有效性。
但是问题跟着就来了,这个Model的属性由于加了Remote特性,在Creat的时候,自动验证有效性没有问题,在Edit的时候却麻烦大了。因为Edit的时候还是回去检测这个数据是否在数据库存在。然而在这个项目中Edit却并不需要这个功能。
在网上找了找资料,发现有一篇博文介绍解决方案的。采取的方式是根据View的功能不同,而定制不同的Model。该作者对MVC的理解是Model应该根据View而变化。他的观点也比较有道理。
但是在我的这个地方,我认为另写个Model类来应对这个变化是没有必要的。因为只有一个字段需要此验证,只有一句代码不同,另建一个Model实在是太重复代码了。
弄来弄去,折腾了一下午。发现了有意思的地方。
这个Remote特性标记将来在View生成HTML的时候会产生固定的代码,关键具体代码如下:
1 <input class="text-box single-line" data-val="true" data-val-length="故障标题字符个数在2-200个之间!" data-val-length-max="200" data-val-length-min="2"
data-val-remote="该故障标题已存在!" data-val-remote-additionalfields="*.Title" data-val-remote-type="post" data-val-remote-url="/FaultManual/GetFaultByTitle"
data-val-required="请填写故障标题" id="Title" name="Title" type="text" value="" /> 2 <span class="field-validation-valid" data-valmsg-for="Title" data-valmsg-replace="true"></span>
请特别注意上面加粗加下划线的这段代码。这是jquery使用特定的标签属性来描述将来验证的属性。对应到了Remote特性标记指定的值。
尝试去掉Model里面的Remote特性标记的时候,这段代码不生成出来。
呵呵,这就好办了。MVC的灵活性非常好。干脆去掉Model里面的Remote特性标记,在View中给这个TexitFor添加指定的Html属性就可以了嘛!
关键代码如下:
Model中代码如下:
1 [Display(AutoGenerateField=true,Name="故障标题")] 2 [Required(AllowEmptyStrings=false,ErrorMessage="请填写故障标题")] 3 [StringLength(200,ErrorMessage="故障标题字符个数在2-200个之间!",MinimumLength=2)] 4 public string Title { get; set; }
Controller中的代码没有变化。
View中代码如下:
1 <div class="editor-field"> 2 @Html.TextBoxFor(model => model.Title,
new Dictionary<string,object>{{"data-val-remote","该故障标题已存在!"},
{"data-val-remote-additionalfields","*.Title"},
{"data-val-remote-type","post"},
{" data-val-remote-url","/FaultManual/GetFaultByTitle"}})
4 @Html.ValidationMessageFor(model => model.Title) 5 </div>
问题解决!