Поделиться через


Добавление проверки в модель (C#)

Рик Андерсон

Примечание.

Обновленная версия этого руководства доступна здесь , где используется ASP.NET MVC 5 и Visual Studio 2013. Это более безопасно, гораздо проще следовать и демонстрирует больше функций.

В этом руководстве описаны основы создания веб-приложения MVC ASP.NET MVC с помощью Microsoft Visual Web Developer 2010 Express с пакетом обновления 1 (SP1), который является бесплатной версией Microsoft Visual Studio. Перед началом работы убедитесь, что вы установили необходимые компоненты, перечисленные ниже. Все их можно установить, щелкнув следующую ссылку: установщик веб-платформы. Кроме того, можно установить предварительные требования по отдельности, используя следующие ссылки:

Если вы используете Visual Studio 2010 вместо Visual Web Developer 2010, установите необходимые компоненты, щелкнув следующую ссылку: предварительные требования Visual Studio 2010.

Проект Visual Web Developer с исходным кодом C# доступен для сопровождения этого раздела. Скачайте версию C#. Если вы предпочитаете Visual Basic, перейдите на версию этого руководства visual Basic.

В этом разделе вы добавите логику проверки в Movie модель и убедитесь, что правила проверки применяются в любое время, когда пользователь пытается создать или изменить фильм с помощью приложения.

Сохранение вещей DRY

Одним из основных принципов дизайна ASP.NET MVC является DRY ("Не повторять себя"). ASP.NET MVC рекомендует указывать функциональные возможности или поведение только один раз, а затем отражать его везде в приложении. Это сокращает объем кода, который необходимо написать, и делает код, который вы делаете, гораздо проще поддерживать.

Поддержка проверки, предоставляемая ASP.NET MVC и Entity Framework Code First, является отличным примером принципа DRY в действии. Вы можете декларативно указать правила проверки в одном месте (в классе модели), а затем эти правила применяются везде в приложении.

Давайте рассмотрим, как воспользоваться этой поддержкой проверки в приложении фильма.

Добавление правил проверки в модель фильма

Начнем с добавления логики проверки в Movie класс.

Откройте файл Movie.cs. using Добавьте инструкцию в верхней части файла, ссылающегося System.ComponentModel.DataAnnotations на пространство имен:

using System.ComponentModel.DataAnnotations;

Пространство имен является частью платформа .NET Framework. Он предоставляет встроенный набор атрибутов проверки, которые можно применять декларативно к любому классу или свойству.

Теперь обновите Movie класс, чтобы воспользоваться встроенными Requiredатрибутами и StringLengthRange атрибутами проверки. Используйте следующий код в качестве примера того, где применять атрибуты.

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

    [Required(ErrorMessage = "Title is required")]
    public string Title { get; set; }

    [Required(ErrorMessage = "Date is required")]
    public DateTime ReleaseDate { get; set; }

    [Required(ErrorMessage = "Genre must be specified")]
    public string Genre { get; set; }

    [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
    public decimal Price { get; set; }

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

Атрибуты проверки определяют поведение для свойств модели, к которым они применяются. Атрибут указывает, что свойство должно иметь значение. В Required этом примере фильм должен иметь значения для Titleсвойств , ReleaseDateGenreи Price свойств, чтобы быть допустимыми. атрибут Range ограничивает значения указанным диапазоном. Атрибут StringLength позволяет задать максимальную и при необходимости минимальную длину строкового свойства.

Code First гарантирует, что правила проверки, указанные в классе модели, применяются перед сохранением изменений в базе данных приложением. Например, приведенный ниже код создает исключение при SaveChanges вызове метода, так как отсутствуют несколько обязательных Movie значений свойств, а цена равна нулю (которая выходит из допустимого диапазона).

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 validation exception

Автоматическое применение правил проверки платформа .NET Framework помогает сделать приложение более надежным. Это также гарантирует, что в любом случае будут выполнены все проверки и в базе данных не будут случайно оставлены поврежденные данные.

Ниже приведен полный список кода для обновленного файла Movie.cs :

using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int ID { get; set; }

        [Required(ErrorMessage = "Title is required")]
        public string Title { get; set; }

        public DateTime ReleaseDate { get; set; }

        [Required(ErrorMessage = "Genre must be specified")]
        public string Genre { get; set; }

        [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
        public decimal Price { get; set; }

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

    public class MovieDBContext : DbContext
    {
        public DbSet<Movie> Movies { get; set; }
    }
}

Пользовательский интерфейс ошибки проверки в ASP.NET MVC

Повторно запустите приложение и перейдите по URL-адресу /Movies .

Щелкните ссылку "Создать фильм", чтобы добавить новый фильм. Заполните форму недопустимыми значениями и нажмите кнопку "Создать ".

8_validationErrors

Обратите внимание, что форма автоматически использовала цвет фона для выделения текстовых полей, содержащих недопустимые данные, и создало соответствующее сообщение об ошибке проверки рядом с каждым. Сообщения об ошибках соответствуют строкам ошибок, заданным при аннотации Movie класса. Ошибки применяются как на стороне клиента (с помощью JavaScript), так и на стороне сервера (если пользователь отключил JavaScript).

Реальное преимущество заключается в том, что вам не нужно изменять одну строку кода в MoviesController классе или в представлении Create.cshtml , чтобы включить этот пользовательский интерфейс проверки. Контроллер и представления, созданные ранее в этом руководстве, автоматически выбрали правила проверки, указанные с помощью атрибутов в Movie классе модели.

Как выполняется проверка в методе создания представления и создания действия

Вам может быть интересно, как пользовательский интерфейс проверки создается без обновления кода контроллера или представлений. В следующем списке MovieController показано, как Create выглядят методы в классе. Они не изменяются из того, как вы создали их ранее в этом руководстве.

//
// 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);
}

Первый метод действия отображает начальную форму создания. Второй обрабатывает запись формы. Второй Create метод вызывает ModelState.IsValid проверку, чтобы проверить наличие ошибок проверки в фильме. При вызове этого метода оцениваются все атрибуты проверки, которые были применены к объекту. Если объект имеет ошибки проверки, Create метод переиграет форму. Если ошибок нет, метод сохраняет новый фильм в базе данных.

Ниже приведен шаблон представления Create.cshtml , который вы создали ранее в руководстве. Он используется в показанных выше методах действия для отображения исходной формы и повторного вывода формы в случае ошибки.

@model MvcMovie.Models.Movie
@{
    ViewBag.Title = "Create";
}
<h2>
    Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></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>

Обратите внимание, что код использует вспомогательный Html.EditorFor элемент для вывода <input> элемента для каждого Movie свойства. Рядом с этим вспомогательным методом является вызов вспомогательного Html.ValidationMessageFor метода. Эти два вспомогательных метода работают с объектом модели, передаваемым контроллером в представление (в данном случае Movie — объект). Они автоматически ищут атрибуты проверки, указанные в модели, и отображают сообщения об ошибках соответствующим образом.

Что действительно хорошо об этом подходе заключается в том, что ни контроллер, ни шаблон создания представления ничего не знает о фактических правилах проверки, применяемых или о конкретных сообщениях об ошибках, отображаемых. Правила проверки и строки ошибок указываются только в классе Movie.

Если вы хотите изменить логику проверки позже, это можно сделать ровно в одном месте. Вам не придется беспокоиться о несогласованности применения правил в различных частях приложения, поскольку вся логика проверки будет определена в одном месте и начнет применяться по всему приложению. Это позволяет максимально оптимизировать код и обеспечить удобство его совершенствования и поддержки. Кроме того, таким образом вы будете полностью соблюдать требования принципа "Не повторяйся".

Добавление форматирования в модель фильма

Откройте файл Movie.cs. В пространстве имен System.ComponentModel.DataAnnotations в дополнение к набору встроенных атрибутов проверки предоставляются атрибуты форматирования. Атрибут и значение перечисления будут применяться DisplayFormat к дате выпуска и DataType к полям цен. В следующем коде показаны свойства ReleaseDate и Price с соответствующим атрибутом DisplayFormat.

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

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

Кроме того, можно явно задать DataFormatString значение. В следующем коде показано свойство даты выпуска со строкой формата даты (например, "d"). Это можно использовать для указания того, что вы не хотите время в рамках даты выпуска.

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

Следующий код форматирует свойство как валюту Price .

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

Movie Полный класс показан ниже.

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

    [Required(ErrorMessage = "Title is required")]
    public string Title { get; set; }

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

    [Required(ErrorMessage = "Genre must be specified")]
    public string Genre { get; set; }

    [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
    [DisplayFormat(DataFormatString = "{0:c}")]
    public decimal Price { get; set; }

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

Запустите приложение и перейдите к контроллеру Movies .

8_format_SM

В следующей части этой серии мы рассмотрим приложение и внесем ряд изменений в автоматически создаваемые методы Details и Delete.