48

EDITAR - Estamos utilizando MVC4 Dev Vista preliminar ....¿Revalidar un ViewModel modificado dentro de un método de controlador?

estoy poniendo en práctica una página de edición para una clase FishingTrip. FishingTrip contiene una colección secundaria de objetos simples Crew (es decir, FishingTripID, CrewID, CrewPosition).

Estoy usando Jarrett Meyer's approach para agregar, editar y eliminar de la colección Crew. Estoy usando una validación discreta para especificar que las propiedades de Crew son todas Required.

Mi problema: cuando, lógicamente, elimino un elemento de la lista (según el método de Jarrett), no quiero que ese elemento sea validado.

He modificado correctamente el método "removeRow" en el lado del cliente para desactivar la validación discreta para el elemento eliminado lógicamente, para que el formulario se publique a pesar de que haya un elemento que contenga campos en blanco.

En mi método controlador [HttpPost] Edit, ModelState.IsValid comienza como falsa (como era de esperar -. A causa del elemento eliminado lógicamente que contiene campos en blanco) De modo que se elimine este punto de mi modelo de vista .... pero ModelState.IsValid sigue siendo falsa.

En resumen, yo (creo que) quiero modificar mi ViewModel dentro del método del controlador para eliminar el elemento ofensivo, luego llamar a algún tipo de "revalidar" y hacer que ModelState.IsValid aparezca como verdadero.

¿Alguna idea?

+0

Posible duplicado de [invocando manualmente la validación ModelState] (http://stackoverflow.com/questions/6360087/manual-invocación-modelo-estado-validación) – KyleMit

Respuesta

111

Una vez que haya eliminado el artículo (s) infractor, desactive la ModelState y validar de nuevo, así:

ModelState.Clear(); 
TryValidateModel(crew); // assumes the model being passed is named "crew" 

Nota: Tenga cuidado cuando se utilice el método TryValidateModel ya que este método no valida objeto anidado de modelo (como lo menciona @Merenzo).

+3

Gracias @councellorben - ModelState.Clear de hecho elimina esos errores (y toda la colección ModelState.Keys) pero TryModelValidate no parece repoblar el ModelState. No parece hacer nada? p.ej. Si no elimino el elemento ofensivo, llamo a .Clear, y luego a TryValidateModel, me queda un modelo de estado en blanco, en lugar de uno que coincide con la versión "pre-Clear()". – Merenzo

+0

Si revisa el código fuente MVC (TryValidateModel en Controller.cs en System.Web.Mvc), TryValidateModel agrega cualquier error al ModelState, y lo he usado para ese propósito en proyectos severos. – counsellorben

+0

@councellorben: en sus proyectos, Clear() elimina todas las ModedlState.Keys, y ¿TryValidateModel restaura todas estas claves * y * agrega los errores a las claves? (Disculpas, estamos utilizando MVC4, no MVC3, como dije originalmente). – Merenzo

2

tarde al juego, pero aún así: Yo también estaba buscando una manera de validar el modelo después hacer algunos ajustes a la misma (más precisamente - a los artículos de su colección anidada) - y TryValidateModel no funcionó para mí, ya que no procesa objetos anidados.

Por último, me conformé con el modelo personalizado de aglutinante:

public class MyItemModelBinder : DefaultModelBinder 
{ 
    protected override void OnModelUpdated(
     ControllerContext controllerContext, 
     ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType == typeof(MyItemModel)) 
     { 
      MyItemModel item = (MyItemModel)bindingContext.Model; 
      //do required tweaks on model here 
      //(I needed to load some additional data from DB) 
     } 
     //validation code will be called here, in OnModelUpdated implementation 
     base.OnModelUpdated(controllerContext, bindingContext); 
    } 
} 

en la clase del modelo:

[ModelBinder(typeof(MyItemModelBinder))] 
public class MyItemModel : IValidatableObject 
{ 
    //... 
} 
+0

Estoy intentando que los atributos de DataAnnotación se validen de nuevo, pero no parecen después de OnModelUpdated. ¿Algunas ideas? – xr280xr

+0

Creé y apliqué un archivador de modelo personalizado para el modelo de vista principal. Necesitaba aplicarlo a la máquina virtual hija que contenía directamente la validación. – xr280xr

Cuestiones relacionadas