Валидация Datetime полей при переводе проекта от ASP.NET MVC 3 к ASP.NET MVC 4

в 8:14, , рубрики: .net, asp.net mvc 4, datetime, razor, валидация, Веб-разработка, метки: , , ,

Описание

Недавно решил попробовать новую версии платформы ASP.NET MVC 4, и перевел проект с MVC 3 на MVC 4.
И тут возникли нежданно, негаданно проблемы (хотя кого я обманываю, переход на бета версию всегда означает некий риск) с валидацией на клиентской стороне полей типа Datetime. Внезапно представление отказывалось валидировать такие поля, хотя раньше они проходили ее, учитывая тот факт что настройки для культур сервера и представления остались те же.

В поисках проблемы

Спустя некоторое время, после того как я вырвал все волосы на голове от истерик и измучил своих коллег на работе этой проблемой, обнаружил, что MVC 3 и MVC 4 используют разные версии Razor View Engine, у которых хелпер EditorFor выполнялся по разному. Вот пример кода использования:

@Html.EditorFor(model => model.Birthdate)

В результате для Razor'a второй версии от MVC 4 создавался input с атрибутом data_val=«true», а для MVC 3 такой атрибут просто напросто отсутствовал, что означало отсутствие валидации на стороне клиента.

Решение

Я предполагаю, что проблему можно решить двумя способами:

  • Изменение jquery.validation.js, который встроен в проект по умолчанию, но это мягко говоря не очень хороший способ
  • Создание своего собственного хелпера, который создавал input без этого аттрибута

Вот пример такого хелпера, так сказать на скорую руку:
public static class DatetimeHelpers
{
public static IHtmlString Date(this HtmlHelper helper, string name, object value)
{
return Date(helper, name, value, null);
}

public static IHtmlString Date(this HtmlHelper helper, string name, object value, object htmlAttributes)
{
var tagBuilder = new TagBuilder("input");
tagBuilder.Attributes["name"] = name;
tagBuilder.Attributes["value"] = value.ToString();
tagBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

return MvcHtmlString.Create(tagBuilder.ToString());
}
}

А вот пример использования:
@Html.Date("Birthdate", Model.Birthdate, new { id = "Birthdate" })

Возможно у Вас тоже была схожая проблема, и мне интересно узнать, как Вы справились с ней.
Спасибо за внимание.

Автор: FinDK


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js