Добавление проверки достоверности
126ASP.NET --- Интернет магазин на ASP.NET Web Forms --- Добавление проверки достоверности
Исходный код проектаБазовый процесс оплаты реализован в предыдущей статье, однако нужно еще добавить средства проверки достоверности, гарантирующие, что пользователь не сможет завершить процесс, не предоставив необходимой информации. В примере ниже демонстрируется применение атрибута Required к некоторым свойствам в классе Order:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace GameStore.Models
{
public class Order
{
public int OrderId { get; set; }
[Required(ErrorMessage="Пожалуйста введите свое имя")]
public string Name { get; set; }
[Required(ErrorMessage="Вы должны указать хотя бы один адрес доставки")]
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
[Required(ErrorMessage="Пожалуйста укажите город, куда нужно доставить заказ")]
public string City { get; set; }
public bool GiftWrap { get; set; }
public bool Dispatched { get; set; }
public virtual List<OrderLine> OrderLines { get; set; }
}
public class OrderLine
{
public int OrderLineId { get; set; }
public Order Order { get; set; }
public Game Game { get; set; }
public int Quantity { get; set; }
}
}
Здесь в свойстве ErrorMessage указываются специальные сообщения об ошибках, отображаемые пользователю, если он не предоставил значение. Элемент управления ValidationSummary был добавлен к веб-форме Checkout.aspx при ее определении. Этот элемент управления будет отображать сообщения об ошибках в ситуации, когда значения в полях формы, помеченных как Required, не были введены:
Этот процесс известен как проверка достоверности серверной стороны и предполагает, что браузер посылает данные формы серверу для проверки, после чего сервер отправляет в качестве ответа завершенную HTML-страницу, включающую сообщения об ошибках.
Описанный процесс не идеален, т.к. он приводит к задержке между моментом отправки пользователем формы и моментом получения отклика о проблемах с введенными данными. Такая задержка вполне может достигать нескольких секунд, если серверы заняты или доступная ширина полосы пропускания ограничена.
Решение заключается в дополнении проверки достоверности серверной стороны проверкой достоверности клиентской стороны, при которой с помощью кода JavaScript выясняется, предоставил ли пользователь подходящие данные, еще до отправки данных формы на сервер.
Проверка достоверности клиентской стороны является дополнением такой проверки на стороне сервера, а не ее заменой. Проверка достоверности клиентской стороны не будет выполняться в браузерах с отключенной поддержкой JavaScript (на удивление распространенная конфигурация). Проверка достоверности серверной стороны — это важная защита от злонамеренных пользователей, пытающихся вставить бессмысленные данные в базу. Проверка достоверности клиентской стороны должна применяться для улучшения пользовательского интерфейса, а проверка достоверности серверной стороны для защиты приложения.
Платформа ASP.NET Framework имеет поддержку проверки достоверности клиентской стороны, но работает она довольно плохо. Вы добавляете в свои веб-формы специальные элементы управления проверкой достоверности, а сервер генерирует код JavaScript, необходимый для выполнения проверки, когда пользователь пытается отправить форму.
С таким подходом связаны серьезные недостатки. Во-первых, не существует способа использования атрибутов проверки (таких как Required), примененных к классам модели данных, для управления процессом проверки достоверности. Это означает дублирование настроек проверки в классе модели (поэтому можно использовать привязку модели в классе отделенного кода) и внутри веб-формы.
Во-вторых, элементы управления проверкой достоверности ASP.NET Framework не работают, когда в классе отделенного кода с помощью привязки модели создаются объекты данных на основе существующих данных, как это делалось в файле Checkout.aspx.cs. Вызов метода TryUpdateModel() приводит к прекращению работы элементов управления проверкой достоверности, т.е. придется выбирать какое-то одно из этих двух средств ASP.NET Framework.
Мы отдаем предпочтение средству привязки модели, а это значит, что мы должны найти альтернативный способ выполнения проверки достоверности на стороне клиента. Применяемый нами подход будет описан в последующих разделах.
Добавление пакетов NuGet
Мы планируем использовать библиотеку jQuery Validation, которая построена на основе базовой функциональности jQuery и поддерживает довольно широкий спектр вариантов проверки достоверности форм. Мы не собираемся работать с библиотекой jQuery Validation напрямую. Вместо этого мы перепрофилируем JavaScript-библиотеку, которую в Microsoft изначально написали для инфраструктуры MVC Framework.
Выберите пункт Manage Nuget Packages (Управлять пакетами NuGet) в меню Project (Проект) среды Visual Studio. В открывшемся окне Manage NuGet Packages (Управление пакетами NuGet) выберите категорию Online (Онлайновые) в левой панели и введите строку поиска "unobstrusive validation" в поле, расположенном в правом верхнем углу. Найдите в списке найденных вариантов пакет Microsoft jQuery Unobtrusive Validation (Ненавязчивая проверка достоверности с помощью jQuery от Microsoft) и щелкните на кнопке Install (Установить), как показано на рисунке ниже:
Ненавязчивый JavaScript — это неточно определенный термин, которым в общем случае обозначается код JavaScript, содержащийся в элементе script или внешнем файле, а не являющийся частью HTML-элементов. В случае проверки достоверности форм это также означает указание желаемого поведения проверки путем добавления атрибутов data к элементам input.
Диспетчер пакетов NuGet загрузит и установит нужные пакеты, включая jQuery и jQuery Validation. Установленные JavaScript-файлы находятся в папке \Scripts.
Нам также необходим пакет Microsoft ASP.NET Web Optimization Framework (Инфраструктура веб-оптимизации Microsoft ASP.NET), который содержит удобные средства для управления JavaScript-файлами. В его состав входит средство упаковки, используемое в следующем разделе. Найдите указанный пакет и добавьте его в проект.
Обновление пакетов
Из-за особенностей упаковки кода мы в конечном итоге получаем старые версии библиотек jQuery и jQuery Validation. Чтобы извлечь последние версии, выберите категорию Updates (Обновления) в левой панели и щелкните на кнопке Update (Обновить) для каждого ранее установленного пакета, как показано на рисунке ниже:
Создание и использование пакета сценариев
Средство пакетов позволяет более просто управлять файлами JavaScript и CSS за счет определения групп связанных файлов и трактовки их как единого модуля. По соглашению относительно настройки пакетов начинать следует с создания нового файла класса по имени BundleConfig.cs в папке App_Start. Код, помещаемый в этот файл, показан в примере ниже:
using System.Web.Optimization;
namespace GameStore
{
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/validation").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js"));
}
}
}
Если Visual Studio не может распознать пространство System.web.Optimization, используемое в примере, то вероятнее всего вы не установили один из пакетов NuGet, как было описано в предыдущем разделе.
Код в методе RegisterBundles() позволяет ссылаться на три файла сценариев, необходимые для проведения проверки достоверности клиентской стороны, как на единый модуль с помощью имени ~/bundles/validation.
Обратите внимание на изменение пространства имен, которое Visual Studio по умолчанию добавляет в файл класса, как это уже делалось для файла RouteConfig.cs.
Наш пакет файлов не является зарегистрированным до тех пор, пока не будет вызван статический метод RegisterBundles(), что делается в файле отделенного кода глобального класса приложения Global.asax.cs, как показано ниже. Это обеспечивает установку конфигурации пакетов при запуске приложения GameStore.
using System;
using System.Web.Routing;
using System.Web.Optimization;
namespace GameStore
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
Далее необходимо применить пакет к мастер-странице \Pages\Store.Master, чтобы среда ASP.NET Framework включила элементы script для трех JavaScript-файлов в HTML-разметку, отправляемую браузеру. В примере ниже показано, как это делается:
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Store.master.cs"
Inherits="GameStore.Pages.Store" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>GameStore</title>
<link rel="stylesheet" href="/Content/Styles.css" />
<%: System.Web.Optimization.Scripts.Render("~/bundles/validation") %>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="header">
<GS:cartsummary runat="server" />
<div class="title">GameStore - магазин компьютерных игр</div>
</div>
<div id="categories">
<GS:CategoryLinks runat="server" />
</div>
<div>
<asp:ContentPlaceHolder ID="bodyContent" runat="server" />
</div>
</div>
</form>
</body>