Pregunta

Utilizo FluentValidation para validar mis modelos de vista ASP.NET MVC 5.1 (usando la validación discreta predeterminada del lado del cliente).Registro/creo mis validadores a través de Ninject (sin atributos en los modelos de vista):

FluentValidationModelValidatorProvider.Configure(x => x.ValidatorFactory = new NinjectValidatorFactory(_kernel));
AssemblyScanner.FindValidatorsInAssembly(Assembly.GetExecutingAssembly()).ForEach(match => _kernel.Bind(match.InterfaceType).To(match.ValidatorType));

Tengo una vista parcial que se utiliza con frecuencia en toda la aplicación.Esta vista parcial tiene su propio modelo de vista.El modelo de vista "principal" (el de la vista completa) simplemente hereda de este modelo de vista "parcial".

public class IndexViewModel : PersonalInfoViewModel { ... }

Se utiliza el mismo patrón en los validadores:

public class IndexValidator : PersonalInfoValidator { ... }

Esto funciona bien y la validación del lado del servidor funciona tan bien como la validación del lado del cliente en la vista "principal".Pero la validación del lado del cliente en la vista parcial no se activa (no data-val-* atributos en los campos de entrada allí).

Mi vista "principal" Index.cshtml

@model IndexViewModel
@Html.TextBoxFor(x => x.SomeProperty) // client-side validation works fine

@Html.Partial("PersonalInfo") // client-side validation in the partial view does not work (see below)

mi vista parcial PersonalInfo.cshtml:

@model PersonalInfoViewModel
@Html.TextBoxFor(x => x.FirstName) // client-side validation does not work

Noté que funciona cuando cambio el modelo de la vista parcial al modelo de vista "principal":

@model IndexViewModel
@Html.TextBoxFor(x => x.FirstName) // client-side validation works

Así que supongo que en algún momento al crear la validación del lado del cliente no se selecciona el validador correcto y no data-val-* Los atributos se inyectan en el HTML.Pero no puedo cambiar el modelo de vista en la vista parcial, porque se usa en varias páginas diferentes con diferentes vistas "principales" (aunque todas heredan de PersonalInfoViewModel).

¿Alguna idea sobre cómo hacer que mi validación del lado del cliente funcione en este caso?

Actualizar

Después de unas horas de investigar el código fuente de ASP.NET WebStack, descubrí que el problema parece ocurrir en el TextBoxFor método.He aquí el ModelMetaData se crea a partir del modelo, y en algún lugar comienza a usar IndexViewModel en lugar de PersonalInfoViewModel para obtener los metadatos para la validación del lado del cliente:

ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Html.GetUnobtrusiveValidationAttributes("FirstName", metadata); // no client-side validation attributes found

Pero esto genera los atributos de validación correctos del lado del cliente si no especifico los metadatos explícitamente:

Html.GetUnobtrusiveValidationAttributes("FirstName");

Desafortunadamente, hasta ahora no he encontrado una manera de utilizar este conocimiento para mi beneficio.

¿Fue útil?

Solución

No pude encontrar una buena solución a mi problema y no quería jugar más con la fuente ASP.NET WebStack, así que me conformé con una fea solución alternativa:

Inyecto "manualmente" lo que falta data-val-* atributos al representar los campos de entrada, como este:

@Html.TextBoxFor(x => x.FirstName, Html.GetUnobtrusiveValidationAttributes("FirstName"))

Desde GetUnobtrusiveValidationAttributes (llamado independiente) crea los atributos HTML correctos. Simplemente los tomo y los agrego a TextBox.Definitivamente no es bonito, pero funciona y puedo seguir con mi trabajo.Si alguien tiene una solución mejor, me encantaría escucharla.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top