您的位置:首页 > Web前端 > HTML

MVC学习之理解ModelState 和验证HTML辅助方法

2009-05-14 13:17 495 查看
理解ModelState 和验证HTML辅助方法
Controller类有一个ModelState属性集合,可以用来提示传递到视图的model对象是否有错误。ModelState中Error记录识别模型属性的名称和错误信息,并允许指定友好的错误信息。

在UpdateModel() 辅助方法给model对象的属性赋值时,如遇到异常或错误,会自动写道ModelState集合中。例如,Dinner对象的EventDate属性的类型为DateTime,当UpdateModel() 方法不能将”EntLib”字符串赋值给EventDate,UpdateModel() 方法将添加一条记录到ModelState集合,说明在给该属性赋值时,发生错误。

开发人员也可以显式写代码,添加错误记录到ModelState集合中,如下代码所示。我们在catch错误处理异常块中,根据Dinner对象中的Rule Vilations(规则冲突)信息,添加到ModelState集合中。
[align=left] [AcceptVerbs(HttpVerbs.Post)][/align]
[align=left] public ActionResult Edit(int id, FormCollection formValues) [/align]
[align=left] {[/align]
[align=left] Dinner dinner = dinnerRepository.GetDinner(id);[/align]
[align=left] [/align]
[align=left] try[/align]
[align=left] {[/align]
[align=left] UpdateModel(dinner);[/align]
[align=left] dinnerRepository.Save();[/align]
[align=left] return RedirectToAction("Details", new { id = dinner.DinnerID });[/align]
[align=left] }[/align]
[align=left] catch[/align]
[align=left] {[/align]
[align=left] foreach (var issue in dinner.GetRuleViolations())[/align]
[align=left] {[/align]
[align=left] ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);[/align]
[align=left] }[/align]
[align=left] return View(dinner);[/align]
[align=left] }[/align]
}

Html 辅助方法和ModelState集成
HTML 辅助方法,如Html.TextBox(),在输出内容时,会检查ModelState集合。如果发现该属性有异常或错误,将呈现用户输入的内容和CSS错误类。

例如,在Edit视图中,我们使用Html.TextBox() 辅助方法呈现Dinner对象的EventDate属性:
<%= Html.TextBox("EventDate", String.Format("{0:g}", Model.EventDate)) %>

当有错的时候呈现视图时,Html.TextBox() 方法检查ModelState集合,检查是否有错误关联到Dinner 对象的EventDate属性。当发现有错误时,将显示用户提交的”EntLib” 输入作为参数值,同时对<input type=”textbox” />元素添加CSS 错误类,如下所示:
<input class="input-validation-error" id="EventDate" name="EventDate"
type="text" value="BOGUS" />

你可以定制CSS错误类的样式。默认的CSS错误类 – input-validation-error定义在\content\site.css 文件中,样式定义如下:
.input-validation-error
{
border: 1px solid #ff0000;
background-color: #ffeeee;
}

CSS样式对输入无效元素的文本框显示如下:



Html.ValidationMessage() 辅助方法
Html.ValidationMessage() 辅助方法用来输出特定Model属性相关的ModelState错误信息:
<%= Html.ValidationMessage("EventDate") %>

上述代码输出:<span class=”field-validation-error”> The value ‘EntLib’ is invalid</span>

Html.ValidationMessage() 辅助方法也支持第二个参数,允许开发人员覆盖错误消息:
<%= Html.ValidationMessage("EventDate", "*") %>
上述代码输出:<span class=”field-validation-error”> *</span>,而不是默认的错误信息。

Html.ValidationSummary() 辅助方法
Html.ValidationSummary() 辅助方法将呈现总结的错误消息,通过<ul><li/></ul>元素列出在ModelState集合中所有详细的错误消息:



Html.ValidationSummary() 辅助方法接收一个可选的字符串参数 – 定义一个概括性的错误消息,并显示在所有详细错误信息的前面:
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
你也可以定义CSS设置错误消息的样式。

使用AddRuleViolations辅助方法
初始的HTTP-POST Edit的实现方法使用了一个foreach循环语句,遍历Dinner对象的Rule Violations,并添加到controller的ModelState集合:
[align=left] catch[/align]
[align=left] {[/align]
[align=left] foreach (var issue in dinner.GetRuleViolations())[/align]
[align=left] {[/align]
[align=left] ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);[/align]
[align=left] }[/align]
[align=left] return View(dinner);[/align]
}

为了使代码更简洁一点,我们添加ControllerHelpers类到NerdDinner项目中,并实现了AddRuleViolations扩展方法,添加了一个对ASP.NET MVC ModelStateDictionary 类的辅助方法。该扩展方法封装了使用RuleViolation 错误信息填充ModelStateDictionary 集合类的逻辑:
[align=left] public static class ControllerHelpers[/align]
[align=left] {[/align]
[align=left] public static void AddRuleViolations(this ModelStateDictionary modelState,[/align]
[align=left] IEnumerable<RuleViolation> errors)[/align]
[align=left] {[/align]
[align=left] foreach (RuleViolation issue in errors)[/align]
[align=left] {[/align]
[align=left] modelState.AddModelError(issue.PropertyName, issue.ErrorMessage);[/align]
[align=left] }[/align]
[align=left] }[/align]
}

接下来,我们更新HTTP-POST Edit方法,使用上述扩展方法实现Dinner的Rule Violations填充ModelState集合。

完成Edit Action方法的实现
下面的代码实现了控制器中Edit的所有逻辑:
[align=left] //[/align]
[align=left] // GET: /Dinners/Edit/2[/align]
[align=left] public ActionResult Edit(int id)[/align]
[align=left] {[/align]
[align=left] Dinner dinner = dinnerRepository.GetDinner(id);[/align]
[align=left] return View(dinner);[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] //[/align]
[align=left] // POST: /Dinners/Edit/2[/align]
[align=left] [AcceptVerbs(HttpVerbs.Post)][/align]
[align=left] public ActionResult Edit(int id, FormCollection formValues) [/align]
[align=left] {[/align]
[align=left] Dinner dinner = dinnerRepository.GetDinner(id);[/align]
[align=left] [/align]
[align=left] try[/align]
[align=left] {[/align]
[align=left] UpdateModel(dinner);[/align]
[align=left] dinnerRepository.Save();[/align]
[align=left] return RedirectToAction("Details", new { id = dinner.DinnerID });[/align]
[align=left] }[/align]
[align=left] catch[/align]
[align=left] {[/align]
[align=left] ModelState.AddRuleViolations(dinner.GetRuleViolations());[/align]
[align=left] return View(dinner);[/align]
[align=left] }[/align]
}

关于Edit方法的实现的优点,不仅Controller类,而且View视图模板都不必关心Dinner模型类的特定验证方法或者业务规则。以后,我们可以针对Model类增加额外的业务规则,而不必要求Controller和View更改代码。这样,我们可以根据需求,以最小的更改代码量,灵活改进应用程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: