8

Creé una vista parcial en una aplicación MVC 3. Este punto de vista tiene un modelo fuertemente tipado como esto:ASP.NET MVC PartialView no emite el marcado de validación

public class ProductViewModel 
{ 
    [Required, Display(Name = "Product price")] 
    public decimal? ProductPrice 
    { 
     get; 

     set; 
    } ... 
} 

En mi método de acción invoco el método PartialView como esto

PartialView("ProductViewModel", products[0]); 

Pero en la página no puedo ver ningún marcado por la lógica de validación y sin embargo no pasa nada si hay errores en la página. Si utilizo esta vista parcial como una plantilla de editor, funciona. Se agradece cualquier ayuda.

Editar: Para ser más específico, tengo un formulario HTML y quiero agregarle marcas a través de la actualización ajax (si el usuario hace clic en un botón, quiero agregar un nuevo marcado a ese formulario). Si incluyo esos controles estáticamente, quiero decir que si los renderizo cuando la página se carga, la validación funciona, pero si agrego controles a esa forma mediante una llamada ajax, no se inserta ninguna marca de validación para esos controles. Mi vista parcial se ve así:

@Html.LabelFor(x => x.ProductPrice) 

@Html.TextBoxFor(x => x.ProductPrice) 

@Html.ValidationMessageFor(x => x.ProductPrice) 

Mi forma se parece a esto:

@using (Html.BeginForm()) 
{ 
    <div id="div_Products"> 
     @Html.EditorFor(x => x) 
    </div> 

    <input type="submit" value="Compare" /> 
} 

El código anterior funciona bien, validación funciona. En el lado del servidor invoco un método de acción que se parece a:

[HttpPost] 
public ActionResult InsertProduct() 
{ 
    var newProductVM = new ProductViewModel{ ProductPrice = 789 }; 

    return PartialView("~/Views/Nutrition/EditorTemplates/ProductViewModel.cshtml", newProductVM); 
} 

me di cuenta de que el motor MVC inserta los validación de marcado sólo si se considera que los controles están dentro de un control de formulario. Cuando trato de actualizar mi control de formulario a través de una llamada ajax, MVC no tiene manera de saber que se colocarán dentro de un elemento de formulario y es por eso que no emite ninguna lógica de validación para ellos, supongo.

+0

Tiene sentido que un editor "emita" errores de validación y demás, y que una vista no lo haga. ¿Podemos ver el código para su vista? – rfmodulator

+0

El problema es que MVC inserta el marcado de validación solo si encuentra que los controles están dentro de un formulario. El problema es que quiero agregar un marcado a un control de formulario mediante la actualización ajax, pero de esta forma el motor MVC no sabe que este marcado se insertará en un elemento de formulario y, por lo tanto, no emite ningún marcado de validación. – Zoliqa

+0

Puede forzarlo con algún código Html.ValidationMessageFor(). Como dije, muéstranos tu opinión, por favor. – rfmodulator

Respuesta

1

¿Habilita la validación no intrusiva en web.config o la vista en sí?

en web.config:

<configuration> 
    <appSettings> 
     <add key="ClientValidationEnabled" value="true"/> 
     <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
    </appSettings> 
</configuration> 

o código dentro:

HtmlHelper.ClientValidationEnabled = true; 
HtmlHelper.UnobtrusiveJavaScriptEnabled = true; 
+0

Su validación funciona correctamente en el editor, por lo que esto nos dice que la configuración es correcta. – rfmodulator

2

En su Vista parcial, agregar este (C#/Razor):

@Html.ValidationMessageFor(model => model.ProductPrice) 
0

El uso de la validación del cliente , es posible volver a validar los elementos cargados después de la carga de la página. Como MVC ahora usa la validación de jQuery, si tiene habilitada la validación del cliente;

jquery validate - validating a field on pageload

Esto podría ayudarle.

10

poner esto en la parte superior de la vista parcial y obtendrá el mensaje de validación dictada en la salida html:

if (this.ViewContext.FormContext == null) 
{ 
    this.ViewContext.FormContext = new FormContext(); 
} 

Si está usando ajax para agregar los campos de formulario que puede desencadenar los nuevos campos a se añaden a la validación, una vez que han sido añadidos a la DOM/Página usar algo como:

$("form").removeData("validator"); 
$("form").removeData("unobtrusiveValidation"); 
$.validator.unobtrusive.parse("form"); 

EDIT/UPDATE (23 Fed 2013): acabo hackeado la FormContext de una vista parcial de la primera vez en Visual Studio 2012 y parece que con las últimas versiones de jQuery y Validation, etc. No necesito agregar las 3 líneas de javascript (arriba) para que la validación funcione dinámicamente sobre ajax, ¡lo que es genial!

+0

Esto funcionó, pero no estoy seguro de entender por qué. –

+0

@ChrisJackson: bueno, viendo el problema simplemente desde una perspectiva de caja negra de alto nivel, sería justo decir que el Html.ValidationMessageFor busca un FormContext no nulo, que normalmente se configuraría usando algo como usar (Html.BeginForm) {- y si no encuentra uno, no molesta en renderizar los mensajes de validación. Supongo que la validación de JS requiere un formulario para funcionar correctamente, por lo que no tiene sentido tener mensajes de validación. IMO es un descuido del equipo de .Net. – Rob

+1

@Rob, gracias, esto curó mi dolor de cabeza! – Netricity

2

No estoy seguro si esto sigue siendo un problema para usted, pero la solución sería llamar:

$.validator.unobtrusive.parse($('#your-new-form-div')); 

después de cargar el formulario de marcado/controles a través de AJAX. Esto analiza los nuevos elementos del formulario y crea la validación del cliente que ha especificado en su vista.

+0

Independientemente de si fue o no un problema para él, fue un problema para mí. Estuve dando vueltas en las profundidades del interwebz toda la tarde maldita buscando esto, sabiendo que iba a ser algo sobre volver a aplicar la validación. Lo único que lamento es que solo tengo un voto para dar. Gracias, amable señor, ya que ahora puedo dejar de correr de cabeza en esta pared de ladrillo que ha sido manchada con una pinta de mi sangre. Oh, no dije $ ('# my-new-form-div'), dije $ ('forma') y todavía funcionó. FYI. – vbullinger

Cuestiones relacionadas