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


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

Рик Андерсон

В этом руководстве описаны основы создания веб-приложения 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 с VB.NET исходный код доступен для сопровождения этого раздела. Скачайте версию VB.NET. Если вы предпочитаете C#, перейдите к версии C# этого руководства.

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

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

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

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

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

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

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

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

Imports System.ComponentModel.DataAnnotations

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

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

Public Class Movie
    Public Property ID() As Integer

    <Required(ErrorMessage:="Title is required")>
    Public Property Title() As String

    <Required(ErrorMessage:="Date is required")>
    Public Property ReleaseDate() As Date

    <Required(ErrorMessage:="Genre must be specified")>
    Public Property Genre() As String

    <Required(ErrorMessage:="Price Required"), Range(1, 100, ErrorMessage:="Price must be between $1 and $100")>
    Public Property Price() As Decimal

    <StringLength(5)>
    Public Property Rating() As String
End Class

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

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

Dim db As New MovieDBContext()

Dim movie As New Movie()
movie.Title = "Gone with the Wind"
movie.Price = 0.0D

db.Movies.Add(movie)
db.SaveChanges() ' <= Will throw validation exception

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

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

Imports System.Data.Entity
Imports System.ComponentModel.DataAnnotations

Public Class Movie
    Public Property ID() As Integer

    <Required(ErrorMessage:="Title is required")>
    Public Property Title() As String

    <Required(ErrorMessage:="Date is required")>
    Public Property ReleaseDate() As Date

    <Required(ErrorMessage:="Genre must be specified")>
    Public Property Genre() As String

    <Required(ErrorMessage:="Price Required"), Range(1, 100, ErrorMessage:="Price must be between $1 and $100")>
    Public Property Price() As Decimal

    <StringLength(5)>
    Public Property Rating() As String
End Class

Public Class MovieDBContext
    Inherits DbContext
    Public Property Movies() As DbSet(Of Movie)
End Class

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

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

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

8_validationErrors

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

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

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

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

'
' GET: /Movies/Create

Function Create() As ViewResult
    Return View()
End Function

'
' POST: /Movies/Create

<HttpPost()>
Function Create(movie As Movie) As ActionResult
    If ModelState.IsValid Then
        db.Movies.Add(movie)
        db.SaveChanges()
        Return RedirectToAction("Index")
    End If

    Return View(movie)
End Function

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

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

@ModelType MvcMovie.Movie

@Code
    ViewData("Title") = "Create"
End Code

<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(Function(model) model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(Function(model) model.Title)
            @Html.ValidationMessageFor(Function(model) model.Title)
        </div>

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

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

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

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

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
End Using

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

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

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

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

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

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

<DataType(DataType.Date)>
    Public Property ReleaseDate() As Date

     <DataType(DataType.Currency)>
    Public Property Price() As Decimal

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

<DisplayFormat(DataFormatString:="{0:d}")>
    Public Property ReleaseDate() As Date

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

<DisplayFormat(DataFormatString:="{0:c}")>
    Public Property Price() As Decimal

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

Public Class Movie
    Public Property ID() As Integer

    <Required(ErrorMessage:="Title is required")>
    Public Property Title() As String

    <Required(ErrorMessage:="Date is required")>
    <DataType(DataType.Date)>
    Public Property ReleaseDate() As Date

    <Required(ErrorMessage:="Genre must be specified")>
    Public Property Genre() As String

    <Required(ErrorMessage:="Price Required"), Range(1, 100, ErrorMessage:="Price must be between $1 and $100")>
    <DataType(DataType.Currency)>
    Public Property Price() As Decimal

    <StringLength(5)>
    Public Property Rating() As String
End Class

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

8_format_SM

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