ASP.NET MVC TryValidateModel () Проблемы при изменении модели - PullRequest
16 голосов
/ 20 декабря 2011

У меня есть двухступенчатый процесс, в котором первый набор данных сохраняется в сеансе.

[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
}

Контроллер

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) возвращает false, говоря, что VideoClip и VideoThumnail требуются, несмотря на то, что они сопоставляются из seesionModel и viewModel.Я добавил точку останова и проверил, что они не равны нулю.

Похоже, что есть некоторые базовые функции, о которых я не знаю, относительно того, как работают ModelState и ValidateModel (), я просто не знаю, что.

ОБНОВЛЕНИЕ

Я бы не сказал, что решил проблему, но нашел обходной путь, который не так хорош, зайдя в ModelState, можно установитьModelValue, используя SetModelValue(), затем вручную удалите ошибку из состояния модели и затем вызовите TryValidateModel() - вам, возможно, даже не придется добавлять значения, просто удалите ошибку, которую я не пробовал.Вот моя работа вокруг.

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);
}

1 Ответ

22 голосов
/ 21 декабря 2011

Во время привязки модели DefaultModelBinder проверяет параметры вашего действия.Поэтому, когда выполнение достигает вашего public ActionResult TvCreate(TvNewsVideoVM modelVM) метода, ModelState уже содержит ошибки проверки.
Когда вы вызываете TryValidateModel, он не очищает ModelState, поэтому ошибки проверки остаютсявот почему он возвращает ложь.Поэтому вам нужно очистить коллекцию ModelState, если вы хотите вручную повторить проверку позже:

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))
   {
     ...
   }
}
...