这篇说一下数据注释验证(Data Annotation Validators

这种验证方式在1.0里是不被支持的,但在.net4.02.0中会被支持。所以如果要在1.0中使用(我用的是vs2008mvc 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 这个(Recommended default)

下载下来后,启动项目,然后生成库文件,就可以在bin/debug里找到这个文件了。

如果不使用下载的System.ComponentModel.DataAnnotations.dll这个库,而使用3.5的,会出现版本冲突。

 

在工程里添加对这两个库的引用,且在Global.asax文件中添加(黑体部分):

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    ModelBinders.Binders.DefaultBinder 
= 
    
new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}

 

这种验证类包含4类修饰:

Range(范围):验证属性的范围值

RegularExpression(正则表达式):以正则表达式来验证属性值(指导中这个词写错了)

Required(不为空):验证属性不为空

StringLength(字串长度):验证字串属性最大长度

 

其中它们的基类是:Validation。有时候如果自定义修饰标签,可以从这个类派生

 

现在还以Customer为例:

[Required(ErrorMessage="名字不能为空")]
[RegularExpression(
@"\d{1}",ErrorMessage="不能大于10")]
[Column(Storage
="_FirstName", DbType="VarChar(50)")]
public string FirstName
{
    ……
}

 

[Required(ErrorMessage = "姓氏不能为空")]
[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 ModelStateDictionary _modelState;
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动作中:

if(!ValiCustomer(customer,this.ModelState))
{
    
return View();
}
return RedirectToAction("Index");

 

这在一定程度上实现了分离

(二)指导中的分离

在提供的指导教程中,把验证做为单独的服务层来做的。而且是在创建时验证。

现在按指导中的例子,把验证做为单独的服务层来做,但不在创建时验证,而是在创建前验证。

public interface ICustomer
{
    
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;
    }
}

 

在动作中:

控制器构造器有动作:

public CustomerController() 
{
    _service 
= new ValiService(this.ModelState);


if (!_service.CreateProduct(customer))
    
return View();
return RedirectToAction("Index");
 

 

当建立mvc应用程序时,应该不要把数据库逻辑放在控制器的动作中进行。对于其它的业务逻辑也要尽量参照这个原则。控制器的动作只用来加载模型,返回视图。对于加载的模型要一次到位(自己这样理解)。

 

posted on 2010-02-09 17:19  梅桦  阅读(1545)  评论(0编辑  收藏  举报