Revalidando um ViewModel modificado dentro de um método de controlador?
-
27-10-2019 - |
Pergunta
EDITAR - Estamos usando MVC4 Dev Preview ....
Estou implementando uma página de edição para uma classe FishingTrip
. FishingTrip
contém uma coleção filho de objetos Crew
simples (ou seja, FishingTripID, CrewID, CrewPosition).
Estou usando a abordagem de Jarrett Meyer para adicionar, editar e excluir da coleção Crew
.
Estou usando a validação discreta para especificar que as propriedades de Crew
são todas Required
.
Meu problema: quando excluo logicamente um item da lista (de acordo com o método de Jarrett), não quero que esse item seja validado.
Eu ajustei com sucesso o método "removeRow" no lado do cliente para desabilitar a validação discreta para o item excluído logicamente, de forma que o formulário será postado apesar de haver um item que contém campos em branco.
Em meu método de controlador [HttpPost] Edit
, ModelState.IsValid
começa como falso (como esperado - por causa do item excluído logicamente que contém campos em branco). Portanto, removo esse item de meu ViewModel .... mas ModelState.IsValid
ainda é falso.
Em resumo, eu (acho que) quero modificar meu ViewModel dentro do método do controlador para remover o item ofensivo, então chamar algum tipo de "revalidação" e ter ModelState.IsValid
mostrado como verdadeiro.
Alguma ideia?
Solução
Depois de remover o (s) item (ns) ofensivo (s), limpe o ModelState e valide novamente, da seguinte maneira:
ModelState.Clear();
TryValidateModel(crew); // assumes the model being passed is named "crew"
Nota : Tenha cuidado ao usar o método TryValidateModel
porque este método não valida o objeto aninhado do modelo (conforme mencionado por @Merenzo).
Outras dicas
Atrasado para o jogo, mas ainda:
Eu também estava procurando uma maneira de validar o modelo depois de fazer alguns ajustes nele (mais precisamente - nos itens de sua coleção aninhada) - e TryValidateModel
não funcionou para mim, pois nãoprocessar objetos aninhados.
Finalmente, resolvi usar o fichário de modelo personalizado:
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);
}
}
na classe do modelo:
[ModelBinder(typeof(MyItemModelBinder))]
public class MyItemModel : IValidatableObject
{
//...
}