asp.net-mvc 在控制器方法中重新验证修改后的 ViewModel?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7833396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:31:43  来源:igfitidea点击:

Revalidating a modified ViewModel within a controller method?

asp.net-mvcasp.net-mvc-3unobtrusive-validationasp.net-mvc-4

提问by Merenzo

EDIT- We're using MVC4 Dev Preview....

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

I'm implementing an edit page for a FishingTripclass. FishingTripcontains a child collection of simple Crewobjects (i.e. FishingTripID, CrewID, CrewPosition).

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

I'm using Jarrett Meyer's approachto add, edit and delete from the Crewcollection. I'm using unobtrusive validation to specify that the properties of Creware all Required.

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

My problem: when I logically-delete an item from the list (as per Jarrett's method), I don't want that item to be validated.

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

I have successfully tweaked the "removeRow" method on the client-side to disable unobtrusive validation for the logically-deleted item, so that the form will post despite there being an item that contains blank fields.

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

In my controller method [HttpPost] Edit, ModelState.IsValidstarts off as false (as expected - because of the logically-deleted item that contains blank fields.) So I remove that item from my ViewModel.... but ModelState.IsValidis still false.

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

In summary, I (think I) want to modify my ViewModel within the controller method to remove the offending item, then call some kind of "revalidate", and have ModelState.IsValidshow up as true.

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

Any ideas?

有任何想法吗?

回答by counsellorben

Once you have removed the offending item(s), clear the ModelState and validate again, like so:

删除违规项目后,清除 ModelState 并再次验证,如下所示:

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

Note: Be carefull when use TryValidateModelmethod because this method does not validate nested object of model (As mentioned by @Merenzo).

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

回答by lxa

Late to the game, but still: I was also looking for a way to validate model afterdoing some tweaks to it (more precisely - to the items of its nested collection) - and TryValidateModeldidn't work for me, as it doesn't process nested objects.

游戏晚了,但仍然:我也在寻找一种方法来验证模型在对它进行一些调整之后(更准确地说 - 对其嵌套集合的项目) - 并且TryValidateModel对我不起作用,因为它没有处理嵌套对象。

Finally, I settled with custom model binder:

最后,我解决了自定义模型绑定器:

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

on the model class:

在模型类上:

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