Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC TryValidateModel() Issues when Model is Modified

I have a two step form process where the first set of data is stored in session.

[IsMp4File]
[Required(ErrorMessage = "* Please select a video to upload")]
public HttpPostedFileBase VideoClip { get; set; }

[Required(ErrorMessage = "* Please select a thumbmail image")]
public HttpPostedFileBase VideoThumbnail{ get;  set; }

public string VideoFileName { get { return VideoClip.FileName; } }

public NewsWizardStep CurrentStep { get; set; }

...

public enum NewsWizardStep : int
{
  One = 1,
  Two = 2,
  Three = 3,
  Four = 4,
  Five = 5,
  Six = 6
}

Controller

public ActionResult TvCreate(TvNewsVideoVM modelVM)
{
   if (modelVM.CurrentStep == NewsWizardStep.Two)
   {
     var sessionModel = ((TvNewsVideoVM)Session["TvModelVM"]);

     modelVM.VideoClip = sessionModel.VideoClip;
     modelVM.VideoThumbnail = sessionModel.VideoThumbnail;
   }

   if (TryValidateModel(modelVM))
   {
     ...
   }
}

TryValidateModel(modelVM) returns false, saying VideoClip and VideoThumnail are required, despite mapping them from the seesionModel to the viewModel. I have added a breakpoint and checked they are not null.

It looks like there is some underlying functionality I am not aware of regarding how ModelState and ValidateModel() work , I just don't know what.

UPDATE

I wouldn't say I have resolved the issue but figured out a workaround that isn't that pretty, By going into the ModelState it is possible to set the ModelValue using SetModelValue() then manually remove the error from the model state and then call TryValidateModel() - you might not even have to add the values just remove the error I have not tried. Here is my work around.

if (modelVM.CurrentStep == NewsWizardStep.Two)
{
  var sessionModel = ((MtTvNewsVideoVM)Session["MtTvModelVM"]);

  modelVM.VideoClip = sessionModel.VideoClip;
  modelVM.VideoThumbnail = sessionModel.VideoThumbnail;

  ModelState.SetModelValue("VideoClip", new  ValueProviderResult(sessionModel.VideoThumbnail, sessionModel.VideoFileName, CultureInfo.CurrentCulture));
                ModelState.SetModelValue("VideoThumbnail", new ValueProviderResult(sessionModel.VideoClip, sessionModel.VideoFileName, CultureInfo.CurrentCulture));

  ModelState["VideoClip"].Errors.RemoveAt(0);
  ModelState["VideoThumbnail"].Errors.RemoveAt(0);
}
like image 668
SimonGates Avatar asked Dec 20 '11 11:12

SimonGates


People also ask

What is TryValidateModel?

The TryValidateModel is like the ValidateModel method except that the TryValidateModel method does not throw an InvalidOperationExceptionexception if the model validation fails.

What does ModelState IsValid validate?

ModelState.IsValid property is an inbuilt property of ASP.Net MVC which verifies two things: 1. Whether the Form values are bound to the Model. 2. All the validations specified inside Model class using Data annotations have been passed.

What is @model in ASP NET MVC?

The Model is the part of MVC which implements the domain logic. In simple terms, this logic is used to handle the data passed between the database and the user interface (UI). The Model is known as domain object or domain entity. The domain objects are stored under the Models folder in ASP.NET.


1 Answers

During the model binding the DefaultModelBinder validates your action parameters. So when the execution hits your public ActionResult TvCreate(TvNewsVideoVM modelVM) method the ModelState is already containing the validation errors.
When you call TryValidateModel it doesn't clear the ModelState so the validation errors remain there that is why it returns false. So you need to clear the ModelState collection if you want to redo the validation later manually:

public ActionResult TvCreate(TvNewsVideoVM modelVM)
{
   ModelState.Clear();

   if (modelVM.CurrentStep == NewsWizardStep.Two)
   {
     var sessionModel = ((TvNewsVideoVM)Session["TvModelVM"]);

     modelVM.VideoClip = sessionModel.VideoClip;
     modelVM.VideoThumbnail = sessionModel.VideoThumbnail;
   }

   if (TryValidateModel(modelVM))
   {
     ...
   }
}
like image 107
nemesv Avatar answered Sep 20 '22 11:09

nemesv