Problem Initialize List for ASP.NET MVC validation

2

I have an action that receives a user file.

[HttpPost]
public ActionResult UpdateFicheiro(FicheiroViewModel model)
{
   var listaDeFicheirosJaAnexados = servico.obtemficheirosJaAnexados();
   model.ficheirosJaAnexados = listaDeFicheirosJaAnexados.toList();

  if(!modelState.IsValid)
  {
     ModelState.AddModelError(string.Empty, "erro!");
     Return View(model);
  }
}

Verify that the file already exists in the database, if it exists the model should be invalid and should show a message to the user saying that the file already exists. But this is not the case, as the list of files is always empty.

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
   if(listaDeFicheirosJaAnexados.contains(ficheiro)) 
      yield return new ValidationResult("ficheiro ja existe na base de dados");           
}

It seems that the Valide method only validates values that it receives from the view. You can remedy this by passing the list of files already attached to the view, hiding it through css and then checking whether the file already exists in the list or not, but it does not seem to be the ideal solution.

I can also create a specific method and pass it to the list, but this would cause my controller to have 3 or 4 more lines of code, and honestly, it also does not seem to me the most correct way to solve the problem.

What I really wanted was that when the Validate method was called, this method would already have access to the list without having to pass it through the view.

Is it possible to do this?

    
asked by anonymous 22.11.2018 / 10:01

1 answer

1

Yes it is possible, but if you want to change the model you are receiving in the action you need to clear the ModelState and then revalidate again.

First it is important that your ViewModel implements the interface IValidatableObject

public class FicheiroViewModel : IValidatableObject
{
    public string Ficheiro { get; set; }
    public List<string> FicheirosJaAnexados { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {

        if (FicheirosJaAnexados != null && FicheirosJaAnexados.Contains(Ficheiro))
            yield return new ValidationResult("ficheiro ja existe na base de dados");
    }
}

In your controller, you must use ModelState.Clear(); and TryValidateModel(model); to check it.

[HttpPost]
public ActionResult UpdateFicheiro(FicheiroViewModel model)
{
    //Limpa o ModelState
    ModelState.Clear();

    //Manipulando a model
    var listaDeFicheirosJaAnexados = new List<string> { "teste"};
    model.FicheirosJaAnexados = listaDeFicheirosJaAnexados;

    //Executanto novamente a validação
    TryValidateModel(model);

    if (!ModelState.IsValid)       
        return View(model);

    // Inclua o seu código para regra de negócio e persistência.
    // ...
    // ...
    // ...

    //Destino da ActionResult no caso de sucesso
    return View("Index");

}

    
22.11.2018 / 15:27