#asp.net-mvc #validation #asp.net-mvc-3 #remote-validation
#asp.net-mvc #проверка #asp.net-mvc-3 #удаленная проверка
Вопрос:
представьте себе такую ситуацию:
Настройка
в проекте MVC3 по умолчанию создайте новый сложный тип в AccountModels.cs
public class GlobalAccount
{
public GlobalAccount()
{
this.LogOn = new LogOnModel();
this.Register = new RegisterModel();
}
public LogOnModel LogOn { get; set; }
public RegisterModel Register { get; set; }
}
В RegisterModel
измените UserName
на:
[Required]
[Remote("UserNameExists", "Validation", "", ErrorMessage = "Username is already taken.")]
[RegularExpression(@"(S) ", ErrorMessage = "White space is not allowed.")]
[Display(Name = "Username (spaces will be stripped, must be at least 6 characters long)")]
public string UserName { get; set; }
UserNameExists
Метод в Validation
контроллере заключается в следующем:
public class ValidationController : Controller
{
public JsonResult UserNameExists(string UserName)
{
string user = null;
if (!String.IsNullOrWhiteSpace(UserName) amp;amp; UserName.Length >= 6)
user = UserName == "abcdef" ? "ok" : null;
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", UserName), JsonRequestBehavior.AllowGet);
}
}
Теперь в представлении регистра используйте GlobalAccount
модель вместо RegisterModel
поле ввода имени пользователя будет выглядеть:
@model Your.NameSpace.Models.GlobalAccount
и
<div class="field fade-label">
@Html.LabelFor(model => model.Register.UserName, new { @class = "text" })
@Html.TextBoxFor(model => model.Register.UserName, new { spellcheck = "false", size = "30" })
</div>
это приведет к чему-то подобному в HTML
<div class="field fade-label">
<label class="text" for="Register_UserName"><span>Username (spaces will be stripped, must be at least 6 characters long)</span></label>
<input data-val="true" data-val-regex="White space is not allowed." data-val-regex-pattern="(S) " data-val-remote="Username is already taken." data-val-remote-additionalfields="*.UserName" data-val-remote-url="/beta/Validation/UserNameExists" data-val-required="The Username (spaces will be stripped, must be at least 6 characters long) field is required." id="Register_UserName" name="Register.UserName" size="30" spellcheck="false" type="text" value="">
</div>
Отладка
Если вы используете FireBug для проверки того, что происходит… удаленная проверка отправляет имя атрибута вместо идентификатора методу проверки ( UserNameExists
одному) как:
Register.UserName
вместо Register_UserName
Поэтому я не могу получить это значение… когда-либо:(
Это действительно ошибка или что-то, что кто-то уже нашел, и я не смог получить, погуглив это?
Вот простое изображение реальной проблемы:
Ответ №1:
Как насчет:
public ActionResult UserNameExists(
[Bind(Include = "UserName")]RegisterModel register
)
{
string user = null;
if (!String.IsNullOrWhiteSpace(register.UserName) amp;amp; register.UserName.Length >= 6)
user = register.UserName == "abcdef" ? "ok" : null;
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet);
}
Другой возможностью является определение специальной модели представления:
public class UserNameExistsViewModel
{
public string UserName { get; set; }
}
и затем:
public ActionResult UserNameExists(UserNameExistsViewModel register)
{
string user = null;
if (!String.IsNullOrWhiteSpace(register.UserName) amp;amp; register.UserName.Length >= 6)
user = register.UserName == "abcdef" ? "ok" : null;
return user == null ?
Json(true, JsonRequestBehavior.AllowGet) :
Json(string.Format("{0} is not available.", register.UserName), JsonRequestBehavior.AllowGet);
}
Что раздражает, так это то, что следующее не работает:
public ActionResult UserNameExists(
[Bind(Prefix = "Register")]string UserName
)
Поди разберись 🙂 Я бы, вероятно, выбрал пользовательскую модель представления. Это выглядит самым чистым.
Комментарии:
1. Я был здесь, смотрел на экран и желал, чтобы ты был онлайн, Дарин 🙂 … Я должен сказать: ВАУ… Я никогда раньше не видел этого трюка, и он работает просто очаровательно 🙂 Разве нам не нравится узнавать что-то новое о нашем любимом языке : D — Мне просто грустно, что я не могу добавить 10 : ( — Очень признателен, Дарин!
2. Я обнаружил, что то, что «раздражает» Дарина, работает для меня, где Bind (Include =»bla») не сработал.
Ответ №2:
Я знаю, что это помечено как ответ, но поскольку у меня такая же проблема, я подумал, что внесу другой вариант, который работает для меня.
Класс в моем случае — «Food», а поле, которое я пытаюсь удаленно проверить, — «Name». Текстовое поле создается редактором для управления:
@Html.EditorFor(model => model.Name)
Удаленная проверка установлена в поле класса питания:
[Remote("FoodNameExists")]
public string Name { get; set; }
И это вызывает метод:
public ActionResult FoodNameExists(string Name) {
Согласно исходному вопросу, вместо того, чтобы передавать это методу FoodNameExists как «Name» или даже «Food_Name», который является значением идентификатора, созданным помощником EditorFor, оно передается как атрибут name, который является «Food.Name «… что, конечно, не является чем-то, что я могу установить в качестве входного параметра.
Итак, мой взлом заключается в том, чтобы просто игнорировать входные параметры и искать в строке запроса:
var name = Request.QueryString["Food.Name"];
… это возвращает правильное значение, которое я проверяю, и я отправляюсь на гонки.
Ответ №3:
Это самый простой способ, который я нашел, чтобы сделать это, просто добавив атрибуты data-val-— в htmlAttributes выпадающего списка for, внутри представления. Следующий метод также работает с удаленной проверкой, если вам не нужна удаленная проверка, просто удалите элементы, содержащие data-val-remote-*:
@Html.DropDownListFor(m => m.yourlistID, (IEnumerable<SelectListItem>)ViewBag.YourListID, String.Empty,
new Dictionary<string, object>() { { "data-val", "true" },
{ "data-val-remote-url", "/Validation/yourremoteval" },
{ "data-val-remote-type", "POST" }, { "data-val-remote-additionalfield", "youradditionalfieldtovalidate" } })
Я надеюсь, что это может помочь. С наилучшими пожеланиями!