Bien, voy a intentar conseguirte el 90% del camino. Esta es en realidad una parte enorme y compleja de MVC 2 y casi imposible de responder en este cuadro de respuesta.
Ahora primero debe ir al blog de Brad Wilsons y leer en profundidad sobre cómo personalizar las plantillas predeterminadas de MVC 2. Eso debería darte una comprensión mucho más clara de todas las partes móviles.
http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html
Ahora voy a empezar un ejemplo sencillo de cómo crear una vista de cita modelo artificial donde queremos para asegurarse de que los valores proporcionados no retroceder en el tiempo. No prestes atención a los atributos en este momento, llegaremos allí.
Aquí es el modelo de vista que estoy usando:
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; }
}
Y He añadido esto a la HomeController defecto (nada de fantasía):
public ActionResult Appointment()
{
return View(new AppointmentViewModel());
}
[HttpPost]
public ActionResult Appointment(AppointmentViewModel appointment)
{
return View(appointment);
}
Y aquí es mi punto de vista:
<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>
Paso 1: Configuración del escenario
Lo primero que debe hacer es tomar las "plantillas predeterminadas" de la entrada del blog. El más importante en este caso es el que se ubicará en /Views/Shared/EditorTemplates/Object.asxc Object.ascx es la piedra angular de toda la operación. Todos los métodos Html.Editor ***** llamarán esto eventualmente.
Ahora la primera pieza de funcionalidad por defecto que tenemos que cambiar es esta línea dentro de Object.ascx
<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
<%= ViewData.ModelMetadata.SimpleDisplayText%>
<% }
Lo que eso es decir es "no muestra ningún tipo complejos anidados" y que no queremos ese. Cambie eso> 1 a a> 2. Ahora, los modelos de vista en su gráfico de objetos tendrán plantillas creadas para ellos en lugar de simplemente crear texto de marcador de posición.
Simplemente mantenga todo lo demás predeterminado por el momento.
* Paso 2: Sustitución de plantillas **
Si usted lee las entradas de blog espero que pueda entender ahora cómo el Editor *** y métodos de visualización llamarán automáticamente las plantillas en Vista/Shared/EditorTemplates y DisplayTemplates . Piense en ellos como si llamaran a Html.RenderPartial ("TYPENAME", MyType) no lo son pero está lo suficientemente cerca en concepto.
Así que si ejecuta la solución hasta aquí y va a la url correcta, notará que MVC 2 llamará a Object.ascx dos veces, una para su AppointmentViewModel y otra para la propiedad DateRange. Fuera de la caja solo se renderiza la misma colección de campos de formulario.
Digamos que queremos hacer que nuestra plantilla rodee nuestro editor DateRange con un recuadro con borde rojo. Lo que queremos hacer es un MVC 2 cortocircuito para llamar a una plantilla personalizada DateTime.ascx en lugar de Object.ascx y eso es tan fácil como agregar nuestra propia plantilla en View/Shared/EditorTemplates/DateRange.ascx. En este caso, sólo he tomado lo que fue generado por Object.ascx trabajar con nuestro modelo DateRange y acaba de pegar el código en un nuevo 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>
Wala!
Ahora, cuando ejecute la solución, debería ver un recuadro rojo alrededor de nuestro DateRange. ¡El resto de las personalizaciones dependen de ti! Puede agregar recuadros jQuery datepicker. En tu caso, puedes poner ambos campos en un solo div para que se alineen horizontalmente. El cielo es el límite en este punto.
Paso 3: Validación:
Validación trabaja más o menos de la manera que cabría esperar. Un atributo [Requerido] dentro de su tipo de DateRange funciona igual que cualquier otro atributo de validación.
Ahora ves que hice un atributo no puedo ir hacia atrás en el tiempo que he puesto en la propiedad DateRange de AppointmentViewModel. Todo lo que tiene que hacer para crear este tipo atributos de validación específico es heredar y poner en práctica el ValidationAttribute de base:
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;
}
}
Ahora bien, si se agrega esto y decorar su propiedad debería ver el mensaje de error que aparece en el atributo de validación CantGoBackwardsInTime personalizado.
Voy a actualizar y aclarar más de esto si tiene algún problema, pero esto debería comenzar y en su camino. (Pensé que podría golpear esto antes de dormir) Solo una advertencia: el nuevo Editor para piezas de MVC 2 es lo más impresionante del mundo y tiene un gran potencial para brindar capacidades de MVC 2 super RAD; sin embargo, hay poco que saber sobre información además del blog de Brad Wilson. Solo sigue y no tengas miedo de mirar el código fuente de MVC 2 si lo necesitas también.
"pero hasta ahora he tenido poca suerte en encontrar soluciones adecuadas". ¿Qué significa eso? – jfar
Hola jfar, soy bastante nuevo en C# y mvc y, por lo tanto, he confiado en las búsquedas de Google para encontrar un buen punto de partida para una solución. El principal ha sido http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx pero no he podido encontrar la manera de agregar validación (del lado del servidor o del lado del cliente). –
Oh bien, pensé que era otra cosa. A menos que alguien más responda, publicaré una respuesta esta noche. Hago este tipo de cosas todo el tiempo. – jfar