1.在Model类里面添加验证,代码如下:
1 public class Movie 2 { 3 public int ID { get; set; } 4 [StringLength(60,MinimumLength=3,ErrorMessage="主题的长度必须在3到60个字符")] 5 public string Title { get; set; } 6 7 [Display(Name="Release Date")] 8 [DataType(DataType.Date)] 9 [DisplayFormat(DataFormatString="{0:yyyy-MM-dd}",ApplyFormatInEditMode=true)] 10 public DateTime ReleaseDate { get; set; } 11 [RegularExpression(@"^[A-Z]+[a-zA-Z''-'s]*$")] 12 [Required] 13 [StringLength(30)] 14 public string Genre { get; set; } 15 [Range(1,100)] 16 [DataType(DataType.Currency)] 17 public decimal Price { get; set; } 18 19 [RegularExpression(@"^[A-Z]+[a-zA-Z''-'s]*$")] 20 public string Rating { get; set; } 21 22 23 }
1 The StringLength attribute sets the maximum length of the string, and it sets this limitation on the database, therefore the database schema will change. Right click on the Movies table in Server explorer and click Open Table Definition: 2 3 这个StringLength属性,设置了最大的字符串长度,限制了数据库,所以数据库结构会改变。我们先来看看数据库结构没改变之前的定义是咋样的:
2.请看图:
3.
1 In the image above, you can see all the string fields are set to NVARCHAR (MAX). We will use migrations to update the schema. Build the solution, and then open the Package Manager Console window and enter the following commands: 2 3 add-migration DataAnnotations 4 update-database 5 6 When this command finishes, Visual Studio opens the class file that defines the new DbMIgration derived class with the name specified (DataAnnotations), and in the Up method you can see the code that updates the schema constraints: 7 8 9 在上面的图片中,你看到,所有的string类型的字段,都是NVARCHAR (MAX),我们将会使用数据库迁移技术,来更新表结构,打开程序包管理器控制台,输入下面的指令: 10 add-migration DataAnnotations 11 update-database 12 13 当这个指令结束之后,VS打开生成的迁移文件,在Up方法中,你看到了添加的数据库约束:
4.请看图片:
5.下面,我们再来打开数据库,看下数据表结构发生了什么变化:
6.
1 The validation attributes specify behavior that you want to enforce on the model properties they are applied to. The Required and MinimumLength attributes indicates that a property must have a value; but nothing prevents a user from entering white space to satisfy this validation. The RegularExpression attribute is used to limit what characters can be input. In the code above, Genre and Rating must use only letters (white space, numbers and special characters are not allowed). The Range attribute constrains a value to within a specified range. The StringLength attribute lets you set the maximum length of a string property, and optionally its minimum length. Value types (such as decimal, int, float, DateTime) are inherently required and don't need the Required attribute. 2 这个验证属性指定了你想要应用到Model中的属性。Required和MinimumLength属性,表明:必须要有一个值,但是不会阻止用户输入一个空格来满足这个验证。RegularExpression属性,用来限制,什么字符可以被输入,在上面的代码中Genre和Rating字段必须只能是字母,(空格,数字还有其他的特殊字符都是不被允许的。),Range属性约束了一个值必须在某个特定的范围之内,StringLength属性让你可以设置,字符串的最大长度,值类型(例如;decilmal,int float,DateTime)都是内在需要的,然而对于Required来说,则并不需要。 3 4 Code First ensures that the validation rules you specify on a model class are enforced before the application saves changes in the database. For example, the code below will throw a DbEntityValidationException exception when the SaveChanges method is called, because several required Movie property values are missing: 5 6 Code First 确保你指定在Model中的验证,在数据库数据保存前,能够被验证。例如下面的代码,当SaveChanges调用的时候,将会抛出一个错误,因为有一些必须要的字段丢失了。
1 MovieDBContext db = new MovieDBContext(); 2 Movie movie = new Movie(); 3 movie.Title = "Gone with the Wind"; 4 db.Movies.Add(movie); 5 db.SaveChanges(); // <= Will throw server side validation exception
7.
1 Having validation rules automatically enforced by the .NET Framework helps make your application more robust. It also ensures that you can't forget to validate something and inadvertently let bad data into the database. 2 3 数据验证,通过 .NET Framework 自动的被执行,这可以使你的程序更健壮,同样它会确保你,不会忘记去验证一些,还有不是故意的要让不好的数据更新到数据库中。
8。下面我们开始验证吧,运行项目;
1 Click the Create New link to add a new movie. Fill out the form with some invalid values. As soon as jQuery client side validation detects the error, it displays an error message. 2 3 点击这个新建的链接,去添加一个新的movie。输入不合法的数据,然后就看到错误了。
1 Note to support jQuery validation for non-English locales that use a comma (",") for a decimal point, you must include the NuGet globalize as described previously in this tutorial.
9.
Notice how the form has automatically used a red border color to highlight the text boxes that contain invalid data and has emitted an appropriate validation error message next to each one. The errors are enforced both client-side (using JavaScript and jQuery) and server-side (in case a user has JavaScript disabled). 注意到:表单自动的使用了一个红色的边框来高亮显示要验证的文本框里面的错误数据。错误消息就显示在旁边。(PS:这里我节省时间,就随便大概翻译一下了,只是把大概的意思翻出来。) A real benefit is that you didn't need to change a single line of code in the MoviesController class or in the Create.cshtml view in order to enable this validation UI. The controller and views you created earlier in this tutorial automatically picked up the validation rules that you specified by using validation attributes on the properties of the Movie model class. Test validation using the Edit action method, and the same validation is applied. 这个真正的好处是,你不必为了可以使用validation UI,而在控制器,或者在视图页面中去改变代码,控制器和视图页面,捕获了你在前面的Model类里面写的验证规则。测试验证,我们使用编辑方法,这个验证同样适用于编辑的功能。 The form data is not sent to the server until there are no client side validation errors. You can verify this by putting a break point in the HTTP Post method, by using the fiddler tool, or the IE F12 developer tools. 表单的数据,不会提交到服务器,除非没有客户端错误的验证机制。你可以在浏览器中按F12,并在Post方法中,设置断点来调试。
10.验证是怎样出现在视图和方法里面的呢:
You might wonder how the validation UI was generated without any updates to the code in the controller or views. The next listing shows what the Create methods in the MovieController class look like. They're unchanged from how you created them earlier in this tutorial. 你可能想到的是这个界面的验证是怎样在没有修改控制器和视图的情况下产生的呢。下面的代码,是控制器的代码,你之前创建的,没有任何修改的
1 public ActionResult Create() 2 { 3 return View(); 4 } 5 // POST: /Movies/Create 6 // To protect from overposting attacks, please enable the specific properties you want to bind to, for 7 // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 8 [HttpPost] 9 [ValidateAntiForgeryToken] 10 public ActionResult Create([Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")] Movie movie) 11 { 12 if (ModelState.IsValid) 13 { 14 db.Movies.Add(movie); 15 db.SaveChanges(); 16 return RedirectToAction("Index"); 17 } 18 return View(movie); 19 }
1 The first (HTTP GET) Create action method displays the initial Create form. The second ([HttpPost]) version handles the form post. The second Create method (The HttpPost version) calls ModelState.IsValid to check whether the movie has any validation errors. Calling this method evaluates any validation attributes that have been applied to the object. If the object has validation errors, the Create method re-displays the form. If there are no errors, the method saves the new movie in the database. In our movie example, the form is not posted to the server when there are validation errors detected on the client side; the second Create method is never called. If you disable JavaScript in your browser, client validation is disabled and the HTTP POST Create method calls ModelState.IsValid to check whether the movie has any validation errors. 2 3 第一个Create方法(HTTP GET)展示初始的数据,第二个Create方法,处理表单的提交。第二个create方法,调用这个ModelState.IsValid 来检查movie实体中是否有验证不通过的数据。通过调用ModelState.IsValid可以来判断是否有验证属性,作用在某个对象上面。如果这个对象出现验证错误,这个Create方法,再次展示表单,如果没有错误,就将数据保存到数据库中。在我们的例子中,当客户端验证出现错误了,表单的数据是不会提交到服务器中的。这第二个Create方法是永远不会被调用的。如果你禁止了浏览器的javascript,客户端的验证会失效,然后这个Post的方式的Create方法会调用ModelState.IsValid来检查,是否Movie实体中有验证不通过的。
11.
1 Below is the Create.cshtml view template that you scaffolded earlier in the tutorial. It's used by the action methods shown above both to display the initial form and to redisplay it in the event of an error. 2 3 (PS:为了节约大家时间,就简单翻译一下了) 4 这句话的大概意思是:下面显示的代码,是用来显示验证失败,而显示的错误消息的:
12.
1 Notice how the code uses an Html.EditorFor helper to output the <input> element for each Movie property. Next to this helper is a call to the Html.ValidationMessageFor helper method. These two helper methods work with the model object that's passed by the controller to the view (in this case, a Movie object). They automatically look for validation attributes specified on the model and display error messages as appropriate. 2 3 What's really nice about this approach is that neither the controller nor the Create view template knows anything about the actual validation rules being enforced or about the specific error messages displayed. The validation rules and the error strings are specified only in the Movie class. These same validation rules are automatically applied to the Edit view and any other views templates you might create that edit your model. 4 5 If you want to change the validation logic later, you can do so in exactly one place by adding validation attributes to the model (in this example, the movie class). You won't have to worry about different parts of the application being inconsistent with how the rules are enforced — all validation logic will be defined in one place and used everywhere. This keeps the code very clean, and makes it easy to maintain and evolve. And it means that that you'll be fully honoring the DRY principle. 6 7 8 这几段话,本来我翻译好了,结果电脑突然关机,没保存。现在就不翻译了,郁闷。。。
直接看代码吧:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Data.Entity; 6 using System.ComponentModel.DataAnnotations; 7 8 namespace MvcMovie.Models 9 { 10 public class Movie 11 { 12 public int ID { get; set; } 13 [StringLength(60,MinimumLength=3,ErrorMessage="主题的长度必须在3到60个字符")] 14 public string Title { get; set; } 15 16 [Display(Name="Release Date")] 17 [DataType(DataType.Date)] 18 [DisplayFormat(DataFormatString="{0:yyyy-MM-dd}",ApplyFormatInEditMode=true)] 19 public DateTime ReleaseDate { get; set; } 20 [RegularExpression(@"^[A-Z]+[a-zA-Z''-'s]*$")] 21 [Required] 22 [StringLength(30)] 23 public string Genre { get; set; } 24 [Range(1,100)] 25 [DataType(DataType.Currency)] 26 public decimal Price { get; set; } 27 28 [RegularExpression(@"^[A-Z]+[a-zA-Z''-'s]*$")] 29 public string Rating { get; set; } 30 31 32 } 33 34 public class MovieDBContext : DbContext 35 { 36 public DbSet<Movie> Movies { get; set; } 37 } 38 }
13.
The DataType attributes only provide hints for the view engine to format the data (and supply attributes such as <a> for URL's and <a href="mailto:EmailAddress.com"> for email. You can use the RegularExpression attribute to validate the format of the data. The DataType attribute is used to specify a data type that is more specific than the database intrinsic type, they are not validation attributes. In this case we only want to keep track of the date, not the date and time. The DataType Enumeration provides for many data types, such as Date, Time, PhoneNumber, Currency, EmailAddress and more. The DataType attribute can also enable the application to automatically provide type-specific features. For example, a mailto: link can be created for DataType.EmailAddress, and a date selector can be provided for DataType.Date in browsers that support HTML5. The DataType attributes emits HTML 5 data- (pronounced data dash) attributes that HTML 5 browsers can understand. The DataType attributes do not provide any validation. DataType属性只是提示了视图引擎来格式化数据。你可以使用RegularExpression属性来验证格式化的数据,DataType不是验证属性,它和数据库差不多,只是指定了数据类型而已,DataType枚举类型,提供了很多数据类型,例如:Date,Time,PhoneNumber,Currency,EmailAddress等等,DataType属性同样能够保证程序可以创建一些特殊的类型,比如a mailto: link 能够被用来创建 DataType.EmailAddress。。。DataType不提供任何的验证。 DataType.Date does not specify the format of the date that is displayed. By default, the data field is displayed according to the default formats based on the server's CultureInfo. DataType.Date 不能指定显示怎样的格式化时间。它是默认根据服务器中的时间来的。 The DisplayFormat attribute is used to explicitly specify the date format:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }
14.
1 The ApplyFormatInEditMode setting specifies that the specified formatting should also be applied when the value is displayed in a text box for editing. (You might not want that for some fields — for example, for currency values, you might not want the currency symbol in the text box for editing.) 2 3 当处于文本编辑模式的时候,ApplyFormatInEditMode属性就会被应用。(你可能不想让这种情况应用于货币类型的字段,因为你不想让货币类型的处于文本编辑模式下) 4 5 6 You can use the DisplayFormat attribute by itself, but it's generally a good idea to use the DataType attribute also. The DataType attribute conveys the semantics of the data as opposed to how to render it on a screen, and provides the following benefits that you don't get with DisplayFormat: 7 8 这个时候,你可以用DisplayFormat,但是一个更好的主意是:使用DataType,这个属性提供了几个好处 9 10 The browser can enable HTML5 features (for example to show a calendar control, the locale-appropriate currency symbol, email links, etc.). 11 浏览器支持HTML5特性 12 By default, the browser will render data using the correct format based on your locale. 13 浏览器默认会在你的本地电脑上面,正确显示数据 14 The DataType attribute can enable MVC to choose the right field template to render the data (the DisplayFormat if used by itself uses the string template). For more information, see Brad Wilson's ASP.NET MVC 2 Templates. (Though written for MVC 2, this article still applies to the current version of ASP.NET MVC.) 15 16 DataType属性能够保证MVC选择正确的字段,显示数据(DisplayFormat它是使用字符串模板),了解更多请看。。。。 17 18 If you use the DataType attribute with a date field, you have to specify the DisplayFormat attribute also in order to ensure that the field renders correctly in Chrome browsers. For more information, see this StackOverflow thread. 19 20 如果你使用了DataType属性,你不得不指定DisplayFormat属性,来确保能够在谷歌浏览器上面,正确显示数据 21 22 Note: jQuery validation does not work with the Range attribute and DateTime. For example, the following code will always display a client side validation error, even when the date is in the specified range: 23 jQuery validation不支持Range,DateTime属性,即使你指定了特定范围,还是会报客户端的验证错误
看代码:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
You will need to disable jQuery date validation to use the Range attribute with DateTime. It's generally not a good practice to compile hard dates in your models, so using the Rangeattribute and DateTime is discouraged.
搞翻译,真不是一件容易的事啊,还是得坚持!加油~~~to myself.