AspNet Mvc一些总结
RestaurantReview.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; using Antlr.Runtime; namespace Kwin.AspNetMvc.OdeToFood.Models { /// <summary> /// /// </summary> /// <remarks> /// 1.Bind特性用于锁定可以进行模型绑定的属性, /// [Bind(Include = "City, Country, Rating")] ,白名单的形式,推荐 /// [Bind(Exclude = "Id, Name")] ,黑名单的形式 /// /// 可以在三个位置设置: /// 1.Global.asax.cs 类型列表中设置绑定规则 /// 2.在类定义上<see cref="RestaurantReview"/> /// 3.在方法参数上 /// -------------------- /// 2.数据验证方法: /// http://developer.51cto.com/art/201404/435126.htm /// http://www.cnblogs.com/zhangkai2237/archive/2012/12/12/2814825.html /// /// 1).数据验证,方法:实现IDataErrorInfo,演示:<see cref="RestaurantReview"/> /// 成员函数在UpadtaModel时会被调用,(永远不要相信客户端,服务器这边再检查一遍) /// -------------------- /// 2).数据验证,方法:继承ValidationAttribute /// 演示MaxWordsAttribute<see cref="MaxWordsAttribute"/> /// 这个特性和普通数据注解的区别是普通数据注解仅仅只能验证Model的一个属性, /// 需要注意的是,自定义的数据注解不支持客户端验证,所有的数据需要提交之后再服务端验证,所以如果要同时实现客户端验证需要自己写js验证 /// /// 3).数据验证,方法:IValidatableObject /// 这个接口是为了实现Model的自验证(self-validating)的,是asp.net mvc3 新增的验证特性。 /// 这个特性和普通数据注解的区别是普通数据注解仅仅只能验证Model的一个属性, /// 而实现了IValidatableObject接口的自验证则在Model的级别来验证 /// /// 4).人工验证 /// </remarks> //[Bind(Include = "Id, Name, City, Country, Rating")] public class RestaurantReview : IValidatableObject // ,IDataErrorInfo { Dictionary<string, string> _errorDictionary = new Dictionary<string, string>(); private int rating; public int Id { get; set; } [Required(ErrorMessage = "{0}不能为空!LoL")] [Display(Name = "名称")] [Remote("CheckNameIsExisted", "Account", HttpMethod = "POST",ErrorMessage = "该用户名已经被使用")] [MaxWords(10,ErrorMessage = "{0}你输入的太多了")] //[StringLength(6)] public string Name { get; set; } [Required] [Display(Name = "城市")] [DisplayFormat(NullDisplayText = "N/A")] public string City { get; set; } [Required] [Display(Name = "国家")] [DisplayFormat(NullDisplayText = "N/A")] public string Country { get; set; } [Required(AllowEmptyStrings = true)] [Display(Name = "等级")] [Range(typeof(int),"1","10",ErrorMessage = "{0}必须是{1}和{2}之间的数字")] public int Rating { get { return this.rating; } set { bool IsNum = Regex.IsMatch(Convert.ToString(value), @"^\d+$"); if (!IsNum) { _errorDictionary.Add("Rating", "等级必须是数字"); } this.rating = value; } } #region IDataErrorInfo Members /// <summary> /// 获取一个单一的错误消息,指示对象实例中的错误 /// </summary> public string Error { get { return string.Empty; //这里没有实现,返回值一个空的错误消息 } } /// <summary> /// 用来接收参数和返回一个错误消息指示属性中的错误 /// </summary> /// <param name="columnName"></param> /// <returns></returns> /// <remarks> /// 服务端再次进行数据验证(原则:永远不要相信客户端)。 /// /UpadtaModel(model)时会调用该方法, /// 如果返回值不为string.Empty,该返回值会被添加到ModelState.Values属性中,并将 /// ModelState.IsValid设置为false。 /// </remarks> public string this[string columnName] { get { if (_errorDictionary.ContainsKey(columnName)) { return _errorDictionary[columnName]; } return string.Empty; } } #endregion #region IValidatableObject /// <summary> /// /// </summary> /// <param name="validationContext"></param> /// <returns>返回类型是 IEnumerable(一种迭代器接口类型)</returns> public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (Rating < 2 && Name.ToLower().Contains("hacker")) { yield return new ValidationResult("sorry,Mr.Hacker, you can't do this", new[] { "Name" }); } } #endregion } }