Andrey on .NET | Проверка данных. Часть 2 (продолжение) – Назначаем атрибуты

Проверка данных. Часть 2 (продолжение) – Назначаем атрибуты

Присвоим стандартные атрибуты свойствам классов Модели разрабатываемого веб-приложения.

Назначаем стандартные атрибуты свойствам Модели

Давайте рассмотрим какие будут сделаны изменения:

Атрибуты [Required] и [StringLength] уже были установлены при указании свойств Модели для Entity Framework. Давайте рассмотрим что еще необходимо к ним добавить.

Начнем с [DataType]. Отметим все свойства типа string как DataType.Text , за исключением следующих:

  • BookDetails.Description – многострочный текст: DataType.MultilineText;
  • BookDetails.Url и Publisher.Homepage – ссылки на веб-страницу: DataType.Url.

Кроме того, для свойств, содержащих ссылку на сайт, с помощью [RegularExpression] установим регулярное выражение, которое будет проверять корректность введенного текста.

Условимся, что рейтинг книги это число от 1 до 5. Укажем это ограничение для свойства Rating при помощи [Range]. Не забудем добавить соответствующее сообщение об ошибке.

Обратите внимание, что атрибуты четко разделяют ответственность между собой. В данном случае,  использование регулярного выражения и ограничение по диапазону не обозначают обязательности ввода значения. Поэтому с точки зрения [RegularExpression] и [Range] значение null является корректным. При необходимости их можно дополнить атрибутом [Required].

Текст сообщений для рассмотренных ошибок добавим в общие ресурсы (ниже в таблице приведены только добавляемые строки):

Файл Resources\Shared\ErrorsRes.resx
InvalidUrl Invalid website address. Не корректный адрес веб-сайта.
ValueOutOfRange {0} should be in the range from {1} ... {2}. Значение вне диапазона.

В результате файлы классов Модели будет выглядеть так:

  • BookDetails.cs
namespace BookCatalog.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using BookCatalog.Resources.Models;
    using BookCatalog.Resources.Shared;

    [Table("Catalog")]
    public class BookDetails
    {
        public int Id { get; set; }

        [Display(Name = "Title", ResourceType = typeof(BookDetailsRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [StringLength(128,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Text)]
        public string Title { get; set; }

        [Display(Name = "Author", ResourceType = typeof(BookDetailsRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [StringLength(128,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Text)]
        public string Author { get; set; }

        [Display(Name = "Language", ResourceType = typeof(BookDetailsRes))]
        [Required(ErrorMessageResourceName = "MustSelectValue",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        public int LanguageId { get; set; }

        public int? PublisherId { get; set; }

        [Display(Name = "PublishedAt", ResourceType = typeof(BookDetailsRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Date)]
        public DateTime PublishedAt { get; set; }

        [Display(Name = "Url", ResourceType = typeof(BookDetailsRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [StringLength(256, MinimumLength = 11,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Url)]
        [RegularExpression(@"(http(s)?://)?([\w-]+\.)+[\w-]+(/[\w- ;,./?%&=]*)?",
            ErrorMessageResourceName = "InvalidUrl",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        public string Url { get; set; }

        [Display(Name = "Description", ResourceType = typeof(BookDetailsRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [StringLength(512, MinimumLength = 32,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.MultilineText)]
        public string Description { get; set; }

        [Display(Name = "Rating", ResourceType = typeof(BookDetailsRes))]
        [Range(1, 5,
            ErrorMessageResourceName = "ValueOutOfRange",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        public int? Rating { get; set; }

        /// <summary>Gets or sets a value indicating whether 
        /// the book is free (true) or not (false).</summary>
        [Display(Name = "IsFree", ResourceType = typeof(BookDetailsRes))]
        public bool IsFree { get; set; }

        /// <summary>Gets or sets a value indicating whether 
        /// the book is visible in the catalog (true) or not (false).</summary>
        [Display(Name = "IsVisible", ResourceType = typeof(BookDetailsRes))]
        public bool IsVisible { get; set; }

        [Display(Name = "Tags", ResourceType = typeof(BookDetailsRes))]
        public virtual ICollection<Tag> Tags { get; set; }

        [Display(Name = "Language", ResourceType = typeof(BookDetailsRes))]
        public virtual Language Language { get; set; }

        [Display(Name = "Publisher", ResourceType = typeof(BookDetailsRes))]
        public virtual Publisher Publisher { get; set; }
    }
}
  • Languages.cs
namespace BookCatalog.Models
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using BookCatalog.Resources.Models;
    using BookCatalog.Resources.Shared;

    public class Language
    {
        public int Id { get; set; }

        [Display(Name = "Name", ResourceType = typeof(LanguageRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [StringLength(64, MinimumLength = 2,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Text)]
        public string Name { get; set; }

        [Display(Name = "Books", ResourceType = typeof(LanguageRes))]
        public virtual ICollection<BookDetails> Books { get; set; }
    }
}
  • Publisher.cs
namespace BookCatalog.Models
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using BookCatalog.Resources.Models;
    using BookCatalog.Resources.Shared;

    public class Publisher
    {
        public int Id { get; set; }

        [Display(Name = "Title", ResourceType = typeof(PublisherRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [StringLength(128,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Text)]
        public string Title { get; set; }

        [Display(Name = "Homepage", ResourceType = typeof(PublisherRes))]
        [StringLength(256, MinimumLength = 7,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Url)]
        [RegularExpression(@"(http(s)?://)?([\w-]+\.)+[\w-]+(/[\w- ;,./?%&=]*)?",
            ErrorMessageResourceName = "InvalidUrl",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        public string Homepage { get; set; }

        [Display(Name = "Books", ResourceType = typeof(PublisherRes))]
        public virtual ICollection<BookDetails> Books { get; set; }
    }
}
  • Tag.cs
namespace BookCatalog.Models
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using BookCatalog.Resources.Models;
    using BookCatalog.Resources.Shared;

    public class Tag
    {
        public int Id { get; set; }

        [Display(Name = "Text", ResourceType = typeof(TagRes))]
        [Required(ErrorMessageResourceName = "FieldIsRequired",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [StringLength(32, MinimumLength = 2,
            ErrorMessageResourceName = "InvalidStringLenght",
            ErrorMessageResourceType = typeof(ErrorsRes))]
        [DataType(DataType.Text)]
        public string Text { get; set; }

        [Display(Name = "Books", ResourceType = typeof(TagRes))]
        public virtual ICollection<BookDetails> Books { get; set; }
    }
}

Запустим веб-приложение. Теперь уже проверяется формат при вводе адресов сайта. Описание книги вводиться в многострочном поле ввода, а при вводе рейтинга необходимо указать число из диапазона.

Но пока что не все ограничения указаны. Например, можно ввести книгу из будущего. Для решения этой проблемы создать свой атрибут, чем и займемся в дальнейшем.


Исходный код проекта (C#, Visual Studio 2010): mvc3-in-depth-validation-02.zip

Добавить комментарий