【问题标题】:How to use same strongly-typed editor view for both create and edit view models?如何为创建和编辑视图模型使用相同的强类型编辑器视图?
【发布时间】:2013-01-10 16:42:22
【问题描述】:

我正在尝试重构编辑器屏幕。编辑器的模型是域模型,我将转到此屏幕的视图模型,因为如果用户具有特定角色,我只需要允许编辑几个字段。我想使用相同的编辑器视图来创建和编辑模型,尽管这可能是我的问题的一部分。

我在 SO 的其他地方读到过,视图模型应该是简单的,因此不需要在视图模型中使用接口层次结构之类的东西。但是,我如何为两种不同的视图模型使用相同的强类型视图,一种用于创建,一种用于编辑,因为视图模型将具有几乎相同但略有不同的属性,具体取决于用户角色?

这是一个使用我创建的两个视图模型的简化示例:

public class RequirementCreateView
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Justification { get; set; }
    public string ImpactIfNotFunded { get; set; }
    ... etc for about 40 properties ...
}

public class RequirementEditView
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Justification { get; set; }
    public string ImpactIfNotFunded { get; set; }
    public string Decision { get; set; }
    public string Status { get; set; }
    ... etc for about 40 properties ...
}

这两个视图模型是相同的,除了编辑模型有两个额外的属性 DecisionStatus 只能由具有适当角色的人设置。我使用 AutoMapper 从域 Requirement 对象映射到视图模型,反之亦然以进行创建/更新操作。

但是,既然我有两个视图模型,显然我不能使用单个强类型编辑器屏幕,因为 ValidationMessageFor(m => Model.Name) 之类的东西不起作用。这促使我考虑为这组视图模型设置一个接口层次结构,如下所示:

IRequirementEditorView             -->  common properties
    |--> IRequirementCreateView    -->  create-specific properties (none right now)
    |--> IRequirementEditView      -->  edit-specific properties

然后让编辑器视图屏幕引用 IRequirementEditorView。但同样,这违背了当前对简单视图模型的看法。但是另一种方法是复制我的编辑器屏幕,这违反了 DRY。

这显然是一个常见问题,但我现在很难过。有什么建议吗?

谢谢。

编辑在查看其他一些类似的帖子后,我应该澄清一下:当我说我使用“相同”的编辑器视图屏幕时,我使用的是两个单独的视图,Create.cshtml 和 Edit .cshtml。然后,它们中的每一个都简单地引用一个包含实际编辑器表单的局部视图,如下所示:

@Html.Partial("Controls/RequirementEditor", Model, ViewData)

当我使用域对象作为视图模型时,这就是我所拥有的。

【问题讨论】:

  • 为什么你觉得使用 Partial 表示两个视图的共同属性是错误的?
  • 我昨天实际上考虑过,但这阻止了我使用像 ValidationMessageFor(m => Model.Name) 这样的表达式,因为它需要一个强类型模型。这让我回到了视图模型的接口层次结构的想法。这样做可以让我使用局部视图,但这违背了我一直阅读的不要过度复杂化视图模型的建议。所以我猜还有另一种思考方式,我还没有摸索。

标签: asp.net-mvc asp.net-mvc-3


【解决方案1】:

原来还有另一种思考方式。在我发布这个问题后不久,我做了一些更改,我对结果更满意。这是我所做的:

  1. 视图模型现在具有额外的布尔属性 AllowDecisionEdit 和 AllowStatusEdit。

  2. 视图模型有两个新的 IEnumerable 属性 DecisionsList 和 StatusList。

  3. 1 和 2 填充到控制器中并传递给适当的视图(创建或编辑)。

  4. 创建视图调用 Html.BeginForm() 然后调用部分 Html.Partial("Controls/RequirementEditor/Editor")。编辑视图的作用相同,但还在部分调用之前添加 Html.HiddenFor(m => Model.Id) 以确保编辑表单正常工作。

所以现在我有一个编辑模型、一个编辑器部分表单、两个单独的视图(创建和编辑),每个视图都使用相同的部分和相同的编辑器,并且在控制器中打开或关闭该功能。我上面的方法闻起来非常非常糟糕,我对任何一种都不满意。一旦我这样做了,世界上的一切都感觉很好。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多