【问题标题】:Is it possible to validate an MVC-3 model without validating "sub-models"?是否可以在不验证“子模型”的情况下验证 MVC-3 模型?
【发布时间】:2011-10-05 18:31:07
【问题描述】:

我有一个需要指定另一个类的类,但我不希望 MVC ModelState 验证器检查辅助模型是否有效。这可能吗?

以下是简要概述:

我的实体看起来像这样:

public class WidgetType
{
    public long Id { get; private set; }

    [Required]
    public string Name { get; set; }

    ...
}

public class Widget
{
    public long Id { get; private set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public WidgetType WidgetType { get; set; }

    ...
}

我将它们封装在一个 WidgetViewModel 类中,我像这样传递到视图/从视图传递:

public class WidgetViewModel
{
    public Widget Widget { get; set; }

    public ICollection<WidgetType> WidgetTypes
    {
        get
        {
            return _repository.GetWidgets();
        }
    }

    ...
}

我的视图看起来像这样:

...
@Html.DropDownListFor( m => m.Widget.WidgetType.Id, new SelectList( new EquipmentViewModel().EquipmentTypes, "Id", "Name" ) )
...

除了验证之外,所有这些都有效。 ModelState.IsValid 始终为 false,因为 "Widget.WidgetType.Name" 是必需的。我需要用户选择一个WidgetType,但我不希望对 ModelState 进行比“Widget.WidgetType.Id”更深的验证(这应该是 Widget 对其外键所需的全部内容?)。

有没有更好的方法来做到这一点?我觉得应该有某种方法来验证,而无需递归检查更深入的属性,但我找不到它。我错过了什么……?

【问题讨论】:

  • 此链接可能会让您了解如何实现部分验证。 blog.stevensanderson.com/2010/02/19/…
  • @bmosh 这看起来很有希望。将在办公室检查一下。
  • @bmosh 创建ActionFilterAttribute 正是我想要的。如果您发布答案,我会接受。谢谢。

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


【解决方案1】:

如果您在视图中只需要 WidgetID,那么您不需要在 WidgetViewModel 中包含整个 Widget。只需拥有名为 WidgetID 的属性。视图模型类应该只包含视图所需的数据。

在提交表单时调用的控制器操作方法中,如果需要,可以使用 WidgetID 从数据库中获取 Widget 对象。

【讨论】:

  • WidgetType 对其他视图很重要,只是在可以设置的编辑页面上没有。我应该为不同的视图设置多个视图模型吗?
  • 通常情况下,每个视图都有一个视图模型类。
【解决方案2】:
public class WidgetViewModel
{    
    [Required]
    public string Name { get; set; }

    [Required]
    public WidgetType WidgetTypeId { get; set; }

    public SelectList WidgetTypes 
    {
        get
        {
             //This should be popuplated in your controller or factory not in the view model
             retun new SelectList{ _repository.GetWidgets(),"Id","Name");

        }
   }
}

在你看来

 @Html.DropDownListFor( m => m.WidgetTypeId, Model.WidgetTypes)

在你的控制器中

public ActionResult Create(WidgetViewModel model)
{
    Widget widget = new Widget{
         Name = model.Name,
         WidgetType = yourManager.GetWidgetTypeByID(model.WigetTypeId);
    };

    yourManager.Create(widget);

    //...
}

【讨论】:

  • 这很有意义,但仍然可以使用ModelState 进行验证吗?
  • @Farray:是的,可以使用 ModelState,因为它将根据您的视图模型类而不是小部件类验证数据
  • 我最终根据 bmosh 的评论实现了自定义 ActionFilterAttribute,但我还根据您的建议重新设计了部分 ViewModel 和 View。感谢您的帮助。
【解决方案3】:
猜你喜欢
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
相关资源
最近更新 更多