【问题标题】:Revalidating a modified ViewModel within a controller method?在控制器方法中重新验证修改后的 ViewModel?
【发布时间】:2011-10-20 08:55:40
【问题描述】:

编辑 - 我们正在使用 MVC4 Dev Preview....

我正在为 FishingTrip 类实现一个编辑页面。 FishingTrip 包含一个简单的 Crew 对象的子集合(即 FishingTripID、CrewID、CrewPosition)。

我正在使用Jarrett Meyer's approachCrew 集合中添加、编辑和删除。 我正在使用不显眼的验证来指定Crew 的属性都是Required

我的问题:当我从列表中逻辑删除一个项目时(根据 Jarrett 的方法),我不希望验证该项目。

我已成功调整客户端的“removeRow”方法,以禁用对逻辑删除项目的不显眼验证,这样即使项目包含空白字段,表单也会发布。

在我的控制器方法[HttpPost] Edit 中,ModelState.IsValid 以 false 开始(正如预期的那样 - 因为逻辑删除的项目包含空白字段。)所以我从我的 ViewModel 中删除了该项目....但是@987654331 @ 仍然是错误的。

总之,我(想我)想在控制器方法中修改我的 ViewModel 以删除有问题的项目,然后调用某种“重新验证”,并让 ModelState.IsValid 显示为真。

有什么想法吗?

【问题讨论】:

标签: asp.net-mvc asp.net-mvc-3 unobtrusive-validation asp.net-mvc-4


【解决方案1】:

一旦您删除了有问题的项目,请清除 ModelState 并再次验证,如下所示:

ModelState.Clear();
TryValidateModel(crew);  // assumes the model being passed is named "crew"

注意:使用TryValidateModel 方法时要小心,因为该方法不验证模型的嵌套对象(如@Merenzo 所述)。

【讨论】:

  • 感谢@councellorben - ModelState.Clear 确实删除了这些错误(以及整个 ModelState.Keys 集合),但 TryModelValidate 似乎没有重新填充 ModelState。它似乎没有做任何事情?例如如果我不删除有问题的项目,然后调用 .Clear,然后调用 TryValidateModel,我会留下一个空白的 ModelState,而不是与“pre-Clear()”版本匹配的。
  • 在我的 MVC4 项目中,我错误地认为 TryValidateModel() 什么都不做......但是它只是忽略了嵌套对象(根据 stackoverflow.com/questions/4465432)。在我的 MVC4 项目中,TryValidateModel() 正在恢复那些 (a) 顶级对象中的键和 (b) 仅当它们有验证错误时。所以在我看来这个答案是正确的。 MVC4 中是否有重大变化是另一回事 :)
  • 那么,如何将 MVC 所做的深度验证复制到模型中呢?我对所有东西都使用 FluentValidation...但是如果我直接应用验证器,它不会更新模型状态。
  • 我花了很长时间才知道如何正确地做到这一点。谢谢你救了我一天的悲伤。
  • 可以使用 TryValidateModel 重载方法 TryValidateModel(model.NestedModel, "NestedModel")
【解决方案2】:

比赛迟到了,但仍然: 我也在寻找一种方法来验证模型对其进行一些调整(更准确地说 - 对其嵌套集合的项目) - 而TryValidateModel 对我不起作用,因为它不起作用'不处理嵌套对象。

最后,我选择了自定义模型绑定器:

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

关于模型类:

[ModelBinder(typeof(MyItemModelBinder))]
public class MyItemModel : IValidatableObject
{
    //...
}

【讨论】:

  • 我试图让 DataAnnotation 属性再次验证,但在 OnModelUpdated 之后它们似乎没有。有什么想法吗?
  • 我创建了一个自定义模型绑定器并将其应用到父视图模型。我需要将其应用于直接包含验证的子 VM。
猜你喜欢
  • 1970-01-01
  • 2014-12-12
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
相关资源
最近更新 更多