在控制器方法中重新验证修改后的 ViewModel?

发布于 2024-12-10 16:30:15 字数 862 浏览 0 评论 0原文

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

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

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

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

我已成功调整客户端上的“removeRow”方法,以禁用对逻辑删除项目的不显眼的验证,以便尽管存在包含空白字段的项目,但表单仍会发布。

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

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

有什么想法吗?

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

I'm implementing an edit page for a FishingTrip class. FishingTrip contains a child collection of simple Crew objects (i.e. FishingTripID, CrewID, CrewPosition).

I'm using Jarrett Meyer's approach to add, edit and delete from the Crew collection.
I'm using unobtrusive validation to specify that the properties of Crew are all 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.

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.

In my controller method [HttpPost] Edit, ModelState.IsValid starts 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.IsValid is still false.

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.IsValid show up as true.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤还要旧人安 2024-12-17 16:30:15

删除有问题的项目后,清除 ModelState 并再次验证,如下所示:

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

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

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

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

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

北渚 2024-12-17 16:30:15

比赛迟到了,但仍然:
我也在寻找一种方法来验证模型之后对其进行一些调整(更准确地说 - 对其嵌套集合的项目) - 并且 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
{
    //...
}

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

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
{
    //...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文