Ладно, я попытаюсь получить 90% пути. На самом деле это огромная и сложная часть MVC 2, и почти невозможно ответить только в этом окне ответа.
Теперь сначала вы должны зайти в блог Брэда Уилсона и подробно прочитать, как настроить шаблоны MVC 2 по умолчанию. Это должно дать вам более четкое понимание всех движущихся частей.
http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html
Теперь я начну с простого примера того, как создать искусственную модель представления встреч, где мы хотим убедиться, что предоставленные значения не возвращаются во времени. Не обращайте внимания на атрибуты прямо сейчас, мы туда доберемся.
Вот модель представления, которую я использую:
public class AppointmentViewModel
{
[Required]
public string Name { get; set; }
[CantGoBackwardsInTime]
public DateRange DateRange { get; set; }
}
public class DateRange
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
[Required]
public int Price { get; set; }
}
И я добавил это к стандартному HomeController (ничего особенного):
public ActionResult Appointment()
{
return View(new AppointmentViewModel());
}
[HttpPost]
public ActionResult Appointment(AppointmentViewModel appointment)
{
return View(appointment);
}
А вот мой взгляд:
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Appointment
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Add Appointment</h2>
<%= Html.ValidationSummary() %>
<% using( Html.BeginForm()) { %>
<%= Html.EditorForModel() %>
<input type="submit" value="Save Changes" />
<%} %>
</asp:Content>
Шаг 1: настройка сцены
Первое, что вы хотите сделать, это взять «шаблоны по умолчанию» из записи в блоге. Важным в этом случае является тот, который будет находиться в /Views/Shared/EditorTemplates/Object.asxc Object.ascx - это краеугольный камень всей операции. Все методы Html.Editor ***** будут вызывать это в конечном итоге.
Теперь первой частью функциональности по умолчанию, которую мы должны изменить, является эта строка внутри Object.ascx
<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
<%= ViewData.ModelMetadata.SimpleDisplayText%>
<% }
То, что говорится: «не отображать вложенные сложные типы», и мы этого не хотим. Измените это> 1 на a> 2. Теперь для просмотра моделей на вашем графе объектов будут созданы шаблоны для них, а не просто текст-заполнитель.
Просто оставьте пока все остальное по умолчанию.
* Шаг 2. Переопределение шаблонов **
Если вы прочитаете записи блога, надеюсь, теперь вы поймете, как методы Editor *** и Display будут автоматически вызывать шаблоны в View / Shared / EditorTemplates и DisplayTemplates. Думайте о них как о вызове Html.RenderPartial («TYPENAME», MyType), но они не достаточно близки по своей концепции.
Так что, если вы запустите решение до этого и перейдете к правильному URL, вы заметите, что MVC 2 будет вызывать Object.ascx дважды, один раз для вашего AppointmentViewModel и снова для свойства DateRange. Из коробки просто визуализируется та же коллекция полей формы.
Допустим, мы хотим, чтобы наш шаблон окружил наш редактор DateRange красной рамкой. Мы хотим, чтобы MVC 2 с коротким замыканием вызывал пользовательский шаблон DateTime.ascx вместо Object.ascx, и это так же просто, как добавить наш собственный шаблон в View / Shared / EditorTemplates / DateRange.ascx. В этом случае я просто взял то, что было сгенерировано Object.ascx, работающим с нашей моделью DateRange, и просто вставил код в новый DateRange.ascx:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div style="border: 1px solid #900">
<div class="editor-label"><label for="DateRange">DateRange</label></div>
<div class="editor-field">
<div class="editor-label"><label for="DateRange_Start">Start</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="DateRange_Start" name="DateRange.Start" type="text" value="" />
</div>
<div class="editor-label"><label for="DateRange_End">End</label></div>
<div class="editor-field">
<input class="text-box single-line" id="DateRange_End" name="DateRange.End" type="text" value="" />
</div>
<div class="editor-label"><label for="DateRange_Price">Price</label></div>
<div class="editor-field">
<input class="text-box single-line" id="DateRange_Price" name="DateRange.Price" type="text" value="" />
</div>
</div>
</div>
Вал!
Теперь, когда вы запускаете решение, вы должны увидеть красное поле вокруг нашего DateRange. Остальные настройки зависят от вас! Вы можете добавить jQuery коробки выбора даты. В вашем случае вы можете поместить оба поля в один элемент div, чтобы они располагались горизонтально. Небо это предел в этой точке.
Шаг 3: Проверка:
Валидация работает практически так, как вы ожидаете. Атрибут [Обязательный] внутри вашего
Тип DateRange работает так же, как и любой другой атрибут проверки.
Теперь вы видите, что я создал атрибут «не могу вернуться назад во времени», который я наложил на свойство DateRange в AppointmentViewModel. Все, что вам нужно сделать, чтобы создать эти специфичные для типа атрибуты проверки, это наследовать и реализовать базовый атрибут ValidationAttribute:
public class CantGoBackwardsInTime : ValidationAttribute
{
public override string FormatErrorMessage(string name)
{
return "Your date range can't go backwards in time";
//return base.FormatErrorMessage(name);
}
public override bool IsValid(object value)
{
if (!(value is DateRange))
throw new InvalidOperationException("This attributes can only be used on DateRange types!");
var dateRange = value as DateRange;
return dateRange.End > dateRange.Start;
}
}
Теперь, если вы добавите это и украсите свое свойство, вы увидите сообщение об ошибке, предоставленное в пользовательском атрибуте проверки CantGoBackwardsInTime.
Я обновлю и уточню больше, если у вас есть какие-либо проблемы, но это должно помочь вам начать работу. (подумал, что я мог бы сделать это перед сном) Просто предупреждение: новый редактор для кусочков MVC 2 - самая удивительная вещь в мире и обладает огромным потенциалом, чтобы дать MVC 2 супер RAD-возможности; Тем не менее, кроме блога Брэда Уилсона, мало что можно узнать. Просто продолжайте и не бойтесь заглянуть в исходный код MVC 2, если вам это тоже нужно.