演练2-6:为模型添加验证规则

原文链接:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-validation-to-the-model

坚持DRY原则

    ASP.NET MVC中的一个设计原则是DRY(“Don't Repeat Yourself”)。相同功能或行为的代码只写一遍,然后在应用程序的任何地方都可以引用。这样减少了代码数量,降低使代码出错可能性,并且更容易维护。

    ASP.NET MVC和Entity Framework Code First中的验证规则设置,就是DRY的一个很好的实践。你可以在模型中声明验证规则,然后这个验证规则就可以在应用程序的各个地方使用。

    接下来我们将在电影网站中使用这个验证规则。

1.在Movie模型中添加验证规则

    修改模型代码,使用Required、StringLength、Range验证属性。

public class Movie {
    public int ID { get; set; }

    [Required]
public string Title { get; set; } [DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } [Required] public string Genre { get; set; } [Range(1, 100)] [DataType(DataType.Currency)] public decimal Price { get; set; } [StringLength(5)] public string Rating { get; set; } }

    运行程序后,得到如下错误。
The model backing the 'MovieDBContext' context has changed since the database  was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

    我们需要进行数据迁移,打开程序包管理器控制台。

add-migration AddDataAnnotationsMig
update-database

    在Up方法中,可以看到模式约束代码。

        public override void Up()
        {
            AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false));
            AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false));
            AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5));
        }
  • Required,必须有值,不能为空。Title、ReleaseDate、Genre、Price都不能为空。值类型(如decimal, int , float, DateTime)是默认为不能为空的。
  • Range,设定数值范围,如Range(1,100)。
  • StringLength(5),设定字符串长度。
MovieDBContext db = new MovieDBContext();

Movie movie = new Movie();
movie.Title = "Gone with the Wind";
movie.Price = 0.0M;

db.Movies.Add(movie);  
db.SaveChanges();        // <= Will throw server side validation exception  

    分析出错原因。

2.验证UI中可能发生的错误

    我们不必在控制器或视图中添加任何代码,去验证字段合法性,控制器和视图会自动获取验证规则。

//
// GET: /Movies/Create

public ActionResult Create()
{
    return View();
}

//
// POST: /Movies/Create

[HttpPost]
public ActionResult Create(Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Movies.Add(movie);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(movie);
}
@model MvcMovie.Models.Movie

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Movie</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ReleaseDate)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ReleaseDate)
            @Html.ValidationMessageFor(model => model.ReleaseDate)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Genre)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Genre)
            @Html.ValidationMessageFor(model => model.Genre)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Price)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Price)
            @Html.ValidationMessageFor(model => model.Price)
        </div>
        <div class="editor-label">
    @Html.LabelFor(model => model.Rating)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Rating)
    @Html.ValidationMessageFor(model => model.Rating)
</div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

 3.在模型中添加格式

    打开Movie.cs文件,System.ComponentModel.DataAnnotations命名空间提供了属性格式。DataType属性并不是验证属性,它们用来告诉视图引擎怎么去渲染HTML,比如DataType.Date只显示日期,并不包括时间。

        [DataType(DataType.Date)] 
        public DateTime ReleaseDate { get; set; }
       
        [DataType(DataType.Currency)] 
        public decimal Price { get; set; }

 

[DataType(DataType.EmailAddress)]
[DataType(DataType.PhoneNumber)]
[DataType(DataType.Url)]

     这些属性知识提供了格式化的数据(<a href="mailto:EmailAddress.com">)。如果需要格式化验证数据,可以使用正则表达式RegularExpressions。

     也可以显式地使用DataFormatString值,如下所示。

       [DisplayFormat(DataFormatString = "{0:d}")]
       public DateTime ReleaseDate { get; set; }

    日期中不需要时间。

       [DisplayFormat(DataFormatString = "{0:c}")]
       public decimal Price { get; set; }

    价格为货币。

public class Movie {
    public int ID { get; set; }

    [Required]
    public string Title { get; set; }

    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Required]
    public string Genre { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    public decimal Price { get; set; }

    [StringLength(5)]
    public string Rating { get; set; }
}

    运行程序,查看功能。

posted @ 2014-09-18 16:22  liesl  阅读(422)  评论(0编辑  收藏  举报