【问题标题】:ASP.NET MVC TryValidateModel() Issues when Model is Modified修改模型时的 ASP.NET MVC TryValidateModel() 问题
【发布时间】:2011-12-20 11:11:40
【问题描述】:

我有一个两步表单流程,其中第一组数据存储在会话中。

[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 可以使用 SetModelValue() 设置 ModelValue 然后手动从模型状态中删除错误然后调用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);
}

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-2 asp.net-mvc-validation


    【解决方案1】:

    在模型绑定期间,DefaultModelBinder 会验证您的操作参数。 因此,当执行到达您的 public ActionResult TvCreate(TvNewsVideoVM modelVM) 方法时 ModelState 已包含验证错误。
    当您调用 TryValidateModel不清除 ModelState 所以验证错误仍然存​​在,这就是它返回 false 的原因。因此,如果您想稍后手动重做验证,则需要清除 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))
       {
         ...
       }
    }
    

    【讨论】:

    • 那更好了谢谢 - 我不明白为什么 TryValidateModel() 方法不先调用 Clear() 方法然后尝试验证模型。
    • 如果您只对手动验证感兴趣,您可以通过使用 装饰 Controller 方法来跳过初始验证魔法
    • ValidateInput false 是这里的关键。它会将值保留在 ModelState 中,但只是跳过自动检查。 ModelState.Clear 很好,但它会清除这些值。
    • 等等,等等,这似乎不是这种情况 - 不确定 ValidateInput 对 ModelState 做了什么
    • 这为我节省了一些搜索时间,甚至没有考虑在它到达我的方法之前设置它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多