dotnetC#今日看点

ASP.NET MVC5----常见的数据注解和验证

2016-09-25  本文已影响429人  Andy阿辉

只要一直走,慢点又何妨。

在使用MVC模式进行开发时,数据注解是经常使用的(模型之上操作),下面是我看书整理的一些常见的用法。

什么是验证,数据注解

验证注解的使用

数据注解定义在一般在命名空间”System.ComponentModel.DataAnnotations”提供了服务器端验证的功能,在模型属性上使用时,框架也支持客户端验证。注解后面都是可以添加错误提示语的,ErrorMessage是每个验证特性中用来设置错误提示消息的参数,比如:

    [Required(ErrorMessage = "不能为空")]
    public int Age { get; set; }

    [Range(typeof(decimal),"0.00","59.99")]
    public decimal Price { get; set; }

Andyahui
    /// <summary>
    /// 验证模型中输入的姓名是否和数据库中重复
    /// </summary>
    /// <returns></returns>
    public JsonResult CheckUserName(string username)
    {            //数据库中的相关验证
        return Json(DateTime.Now.ToString(),JsonRequestBehavior.AllowGet);
    }

    [Remote("CheckUserName", "Admin")]
    public string UserName { get; set; }

上面控制器操作会利用与UserName属性同名的参数进行验证,同时返回一个javascript object Notaion(json)对象中的布尔类型值(0/1)

验证和模型绑定

操作方法中添加参数这里有一个隐式地执行模型绑定,一般我们都需要这样写,这样也安全,不会说暴露出来参数。

利用UpdateModel或TryUpdateModel方法显式执行绑定

这个实际项目中使用的很少,一般都是通过隐式进行转换的。

    [HttpPost,ActionName("Create")]
    public ActionResult CreatePost(Student model)
    {
        var model2 = new Student();
        UpdateModel(model2);
        if (TryUpdateModel(model2))
        {
             
        }
        return View(model);
    }

可以看到参数中的为隐式转换,里面的model2为显式转换。if中的返回的是bool类型。模型绑定器一旦使用新值完成对模型属性的更新,就会利用当前的 模型元数据获得模型的所有验证器。MVC运行时提供了一个验证器(DataAnnotationsModelValidator)来与数据注解一同工作,这个模型验证器会找到所有的验证特性并执行它们包含的验证逻辑,模型绑定器捕获所有失败的验证规则并把它们放入模型状态中。

编程的一个重要原则是不能相信用户的输入

验证与模型状态

模型绑定的副产品是模型状态,也就是我们服务端验证的ModelState,此状态中不仅包含用户的输入,也含有每个相关属性的所有错误(与模型状态本身有关的错误),有错误,ModelState.IsValid就返回false。从而我们就可以进行验证。

    public ActionResult CreatePost(Student model)
    {
        var s=ModelState.IsValidField("UserName");
         var ss=ModelState["UserName"].Errors.Count;
        var userName = ModelState["UserName"].Errors[0].ErrorMessage;  //获取错误消息
        if (ModelState.IsValid)      //返回bool类型
        {                 
        }
        return View(model);
    }

显示和编辑注解

Andyahui
    [ScaffoldColumn(false)]
    public string Address { get; set; }

自定义验证逻辑

1:将验证逻辑封装在自定义的数据注解中。
2:将验证逻辑封装在模型对象中。
把验证逻辑封装在自定义的数据注解中可以轻松地实现在多个模型中重用逻辑。需要在特性内部编写代码以应对不同类型的模型中。

需求:限制用户输入地址中单词数量,设定一个最大值。

/// <summary>
/// 自定义模型验证
/// 输入数字的单词最大数量
/// </summary>
public class MaxWordsAttribute:ValidationAttribute
{
    private readonly int _maxWord;
    public MaxWordsAttribute(int maxWord)
    {
        _maxWord = maxWord;
    }
    protected override ValidationResult IsValid(object value,ValidationContext validationContext)
    {
        if (value!=null)
        {
            //将输入转换为string类型
            var valueAsString = value.ToString();
            //使用split(' ')空格来分隔输入值,统计生成字符串的数量。对数目比较验证。
            if (valueAsString.Split(' ').Length>_maxWord)      
            {
                 return new ValidationResult("单词超过长度");  //string类型
            }
        }
        return ValidationResult.Success;         //bool类型
    }
}

第一个参数要验证对象中的值。后面进行逻辑的判断。这样做这里的错误提示不能显示到前台。我们需要修改下,使用ValidationAttrubute的ErrorMessage属性来自定义提示错误消息。


public class MaxWordsAttribute:ValidationAttribute
{
    private readonly int _maxWord;
    public MaxWordsAttribute(int maxWord)
        :base("{0} has too many words")     
    {
        _maxWord = maxWord;
    }
    protected override ValidationResult IsValid(object value,ValidationContext validationContext)
    {
        if (value!=null)
        {
            //将输入转换为string类型
            var valueAsString = value.ToString();
            //使用split(' ')空格来分隔输入值,统计生成字符串的数量。对数目比较验证。                
            if (valueAsString.Split(' ').Length>_maxWord)
            {
                var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                 return new ValidationResult(errorMessage);  
            }
        }
        return ValidationResult.Success;         //bool类型
    }
}

    [MaxWords(5)]        
    public string Address { get; set; }

这样效果就会将我们基类中的错误信息显示出来。

Andyahui

我们可以模型基础上添加自定义错误显示。

    [MaxWords(5,ErrorMessage = "你输入的单词数超界限,请重新输入。")]        
    public string Address { get; set; }

Andyahui

这里需要注意这里的执行顺序,它是先执行模型上面的验证,接着在到控制器中的action中去的。利用ModelState.IsValid来进行验证。

 public class Information:IValidatableObject
    {
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (UserName!=null&&UserName.Split(' ').Length>5)
            {
                 yield return new ValidationResult("单词超界限了");
            }             
        }
        [Display(Name = "用户名")]
        public string UserName { get; set; }        
    }


Andyahui

其实书上面是在错误返回值中返回的是string类型的数组,如下

yield return new ValidationResult("单词超界限了",new []{"UserName"});可以我不知道从那里取出来这个错误消息。只能单独的显示出来。其实把错误消息放在数组中可以进行多模型的验证,从而统一将错误显示出来。

自己的感觉要是需要模型验证,最好还是进行第一种方法,最起码代码看起来干净,第二种给人的感觉是很乱,但是第二种适合比较模型多的场合。

我就是我,颜色不一样的烟火。

上一篇下一篇

猜你喜欢

热点阅读