这篇说一下数据注释验证(Data Annotation Validators)
这种验证方式在1.0里是不被支持的,但在.net4.0和2.0中会被支持。所以如果要在1.0中使用(我用的是vs2008和mvc 1.0),要一些准备工作:
先要添加两个库文件:
·Microsoft.Web.Mvc.DataAnnotations.dll
·System.ComponentModel.DataAnnotations.dll
这两个都要到网站去下载
http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471
下载Data Annotations Model Binder Sample 这个
下载下来后,启动项目,然后生成库文件,就可以在bin/debug里找到这个文件了。
如果不使用下载的System.ComponentModel.DataAnnotations.dll这个库,而使用3.5的,会出现版本冲突。
在工程里添加对这两个库的引用,且在Global.asax文件中添加(黑体部分):
{
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.DefaultBinder =
new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}
这种验证类包含4类修饰:
Range(范围):验证属性的范围值
RegularExpression(正则表达式):以正则表达式来验证属性值(指导中这个词写错了)
Required(不为空):验证属性不为空
StringLength(字串长度):验证字串属性最大长度
其中它们的基类是:Validation。有时候如果自定义修饰标签,可以从这个类派生
现在还以Customer为例:
[RegularExpression( @" \d{1} " ,ErrorMessage = " 不能大于10 " )]
[Column(Storage = " _FirstName " , DbType = " VarChar(50) " )]
public string FirstName
{
……
}
[Column(Storage = " _LastName " , DbType = " VarChar(50) " )]
public string LastName
{
……
}
这里只贴一部分。因为我这是直接在dbml代码文件里加的,所以多出1行修饰。其中加粗部分为数据注释验证(修饰标签)
在前台的效果如下:
Create
Create was unsuccessful. Please correct
the errors and try again.
FirstName: * LastName: *
|
有些情况下这种验证方式比较好,但在有些情况下这种验证方式并不适合,所以要在不同的环境情况下使用适当的验证方式。
控制器动作中的验证剥离
这里将控制器动作中的验证(一堆的if语句)分离开来,而动作中只判断Customer。
(一)到方法
在控制器中添加:
private bool ValiCustomer(Customer customer,ModelStateDictionary modelState)
{
_modelState = modelState;
if (customer.FirstName == string .Empty)
{
_modelState.AddModelError( " FirstName " , " 名字不能为空! " );
}
if (customer.LastName == string .Empty)
{
_modelState.AddModelError( " LastName " , " 姓氏不能为空! " );
}
if (Convert.ToInt32(customer.FirstName) > 10 )
{
_modelState.AddModelError( " FirstName " , " 名字不能大于! " );
}
return _modelState.IsValid;
}
然后,在Create动作中:
{
return View();
}
return RedirectToAction( " Index " );
这在一定程度上实现了分离
(二)指导中的分离
在提供的指导教程中,把验证做为单独的服务层来做的。而且是在创建时验证。
现在按指导中的例子,把验证做为单独的服务层来做,但不在创建时验证,而是在创建前验证。
{
bool CreateProduct(Customer customerToCreate);
}
public class ValiService : ICustomer
{
private ModelStateDictionary _modelState;
public ValiService(ModelStateDictionary modelState)
{
_modelState = modelState;
}
public bool CreateProduct(Customer customerToCreate)
{
if (customerToCreate.FirstName == string .Empty)
{
_modelState.AddModelError( " FirstName " , " 名字不能为空! " );
}
if (customerToCreate.LastName == string .Empty)
{
_modelState.AddModelError( " LastName " , " 姓氏不能为空! " );
}
if (Convert.ToInt32(customerToCreate.FirstName) > 10 )
{
_modelState.AddModelError( " FirstName " , " 名字不能大于10! " );
}
return _modelState.IsValid;
}
}
在动作中:
控制器构造器有动作:
{
_service = new ValiService( this .ModelState);
}
if ( ! _service.CreateProduct(customer))
return View();
return RedirectToAction( " Index " );
当建立mvc应用程序时,应该不要把数据库逻辑放在控制器的动作中进行。对于其它的业务逻辑也要尽量参照这个原则。控制器的动作只用来加载模型,返回视图。对于加载的模型要一次到位(自己这样理解)。