Осталось реализовать предварительную проверку на стороне клиента для одного свойства – Login. Её особенность в необходимости осуществлять запрос на сервер при каждом изменении пользователем значения в соответствующем поле формы ввода. Можно конечно разработать необходимый функционал самостоятельно и, по сути, заново изобрести колесо. Или воспользоваться возможностями ASP.NET MVC 3.
Проверка данных при помощи атрибута [Remote]
Как можно заметить, сценарий рассматриваемой проверки достаточно однотипный. Необходимо переслать проверяемое значение на сервер, где оно будет проверено, и получить ответ, является ли оно корректным.
В ASP.NET MVC 3 для реализации такого сценария предусмотрен атрибут [Remote], расположенный в пространстве имен System.Web.Mvc. Рассмотрим принципы его использования.
Как и любой другой, данный атрибут вначале необходимо присвоить выбранному свойству в одном из классов Модели. Это задействует в Представлениях механизм, который будет отправлять запросы на сервер при изменении значения соответствующего поля формы ввода.
В качества параметров конструктора [Remote] выступает название Действия, выполняющего необходимую проверку, и имя Контроллера в котором оно расположено. Дополнительные настройки осуществляются при помощи свойств:
- HttpMethod – указывает тип запроса: POST или GET. Последний используется по умолчанию.
- AdditionalFields – позволяет дополнительно передавать в Контроллер значения из указанных полей формы ввода. По умолчанию передается только значение поля, связанного с контролируемым свойством Модели.
После установки атрибута необходимо создать Действие. При этом стоит отметить, что согласно идеологии шаблона MVC, Контроллер не должен выполнять непосредственную проверку полученного значения. Его задача состоит только в определении необходимого метода Модели и переадресации ей проверяемого значения.
Результатом проверки является значение true, если она прошла успешна. В противном случае должно быть возвращено сообщение об ошибке или false, чтобы использовать текст, указанный при установке атрибута. Ответ пересылается Контроллером в клиентскую часть, используя формат Json. Для упрощения этой задачи можно воспользоваться методом Json(). Обработка результата и, при необходимости, вывод сообщения на стороне клиента осуществляется функционалом ASP.NET MVC 3 самостоятельно.
Таким образом, для реализации удаленной проверки данных необходимо выполнить только два действия: назначить атрибут свойству и создать метод проверки значения.
Реализация удаленной проверки свойства Login
Удаленная проверка будет добавлена в NewUserProfileModel. Как и в случае с серверной реализацией, причина заключена в её необходимости только при создании нового профиля.
Для этого в базовом классе UserProfileModel обозначим свойство Login как виртуальное. Это позволит переопределить его в NewUserProfileModel и добавить новый атрибут, унаследовав заданные ра��ее.
Действие, ответственное за проверку, назовем "IsLoginExists". Кроме того, будем использовать запрос типа POST и уже существующей текст сообщения об ошибках.
namespace MVCDemo.Models
{
using System.ComponentModel.DataAnnotations;
using MVCDemo.Attributes.Validation;
using MVCDemo.Resources.Models;
using MVCDemo.Resources.Shared;
public class UserProfileModel
{
[Display(Name = "Login", ResourceType = typeof(UserProfileRes))]
[DataType(DataType.Text)]
[Required(ErrorMessageResourceName = "FieldIsRequired",
ErrorMessageResourceType = typeof(ErrorsRes))]
[StringLengthRange(3, 64,
ErrorMessageResourceName = "InvalidStringLength",
ErrorMessageResourceType = typeof(ErrorsRes))]
public virtual string Login { get; set; }
.........
}
}
namespace MVCDemo.Models
{
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using MVCDemo.Attributes.Validation;
using MVCDemo.Resources.Models;
using MVCDemo.Resources.Shared;
public class NewUserProfileModel : UserProfileModel, IValidatableObject
{
[Remote("IsLoginExists", "UserProfiles", HttpMethod = "POST",
ErrorMessageResourceName = "LoginAlreadyExists",
ErrorMessageResourceType = typeof(NewUserProfileRes))]
public override string Login { get; set; }
}
}
Перейдем к модификации Контроллера. В Модели уже существует метод для проверки уникальности значения имени входа. Поэтому достаточно просто переадресовать ему запрос и вернуть ответ.
namespace MVCDemo.Controllers
{
using System.Web.Mvc;
using MVCDemo.Models;
public class UserProfilesController : Controller
{
.........
// POST: /UserProfiles/IsLoginExists/
[HttpPost]
public JsonResult IsLoginExists(string login)
{
var userRepository = new UserRepository();
bool isExist = userRepository.IsLoginExists(login);
return this.Json(!isExist);
}
}
}
Запустим проект и убедимся в работоспособности сделанных изменений.
Давайте посмотрим, где расположились параметры, заданные для удаленной проверки. Для этого откроем HTML код страницы создания нового профиля:
<div class="editor-label">
<label for="Login">Login</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true"
data-val-remote="Login already exists, please choose another."
data-val-remote-additionalfields="*.Login"
data-val-remote-type="POST"
data-val-remote-url="/UserProfiles/IsLoginExists"
data-val-required="You must enter a Login." data-val-strlenrange="Login length must be between 3 and 64." data-val-strlenrange-max="64" data-val-strlenrange-min="3" id="Login" name="Login" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="Login" data-valmsg-replace="true"></span>
</div>
Как хорошо видно, они разместились в атрибутах соответствующего HTML тега, названия которых начинается с "data-val-remote". Здесь так же используется ненавязчивый JavaScript. Функционал самой проверки, как и для остальных атрибутов, возложен на jQuery Validation.
Реализация запланированных правил проверки свойств Модели завершена. Для этого были использованы возможности ASP.NET MVC, в том числе и представленные в 3 версии.
Исходный код проекта (C#, Visual Studio 2010):
MVCDemo-Part14.zip (477 Kb)