¿Revalidar un ViewModel modificado dentro de un método de controlador?
-
27-10-2019 - |
Pregunta
EDITAR : estamos usando MVC4 Dev Preview ...
Estoy implementando una página de edición para una clase FishingTrip
. FishingTrip
contiene una colección secundaria de objetos Crew
simples (es decir, FishingTripID, CrewID, CrewPosition).
Estoy usando enfoque de Jarrett Meyer 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 elimino lógicamente un elemento de la lista (según el método de Jarrett), no quiero que ese elemento sea validado.
He modificado con éxito el método "removeRow" en el lado del cliente para deshabilitar la validación discreta del elemento eliminado lógicamente, de modo que el formulario se publique a pesar de que haya un elemento que contenga campos en blanco.
En mi método de controlador [HttpPost] Edit
, ModelState.IsValid
comienza como falso (como se esperaba, debido al elemento eliminado lógicamente que contiene campos en blanco). Así que elimino ese elemento de mi ViewModel ... pero ModelState.IsValid
sigue siendo falso.
En resumen, (creo que) quiero modificar mi ViewModel dentro del método del controlador para eliminar el elemento ofensivo, luego llamar a algún tipo de "revalidación" y hacer que ModelState.IsValid
aparezca como verdadero.
¿Alguna idea?
Solución
Una vez que haya eliminado los elementos infractores, borre ModelState y valide nuevamente, así:
ModelState.Clear();
TryValidateModel(crew); // assumes the model being passed is named "crew"
Nota : Tenga cuidado cuando use el método TryValidateModel
porque este método no valida el objeto anidado del modelo (como lo menciona @Merenzo).
Otros consejos
Llegó tarde al juego, pero aún así:
También estaba buscando una manera de validar el modelo después de hacerle algunos ajustes (más precisamente, a los elementos de su colección anidada), y TryValidateModel
no funcionó para mí, ya que noprocesar objetos anidados.
Finalmente, me decidí por la carpeta de modelos personalizados:
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 modelo:
[ModelBinder(typeof(MyItemModelBinder))]
public class MyItemModel : IValidatableObject
{
//...
}