【问题标题】:Using model with multiple types and creating different EditorForModel templates使用具有多种类型的模型并创建不同的 EditorForModel 模板
【发布时间】:2012-02-06 19:59:02
【问题描述】:

我对如何实现 EditorForModel 有点困惑。我想到在 Views\Shared\EditorTemplates 中设置模板,但我认为我已经过度研究(如果可能的话),这导致了我的困惑。

基本上,我会尽量减少代码复制。我向客户提供 5 项服务,每项服务都有 4 到 6 种不同的解决方案。使事情变得更复杂的是,某些类型可以在许多解决方案之间不同程度地共享。

为了简单起见,请输入以下类型:

public string FirstName { get; set; }

我将在每个解决方案中使用它(并在每个服务中上升到“树”)。但显然我还有许多其他类型,它们要么在几个解决方案之间共享,要么根本不共享。

假设每个服务有 100 种类型。我可以将它们分离为不同的视图模型,但是我必须通过 5 个服务来考虑这一点。我更愿意将它们全部保存在一个视图模型中,每项服务。

我在尝试创建模板时遇到了麻烦。我想使用模板,因为我正在使用向导,并且我不想在特定解决方案中为向导的每个部分重新创建视图,特别是如果它是相同的“数据”(并且再次考虑我有多少解决方案)。

因此,我创建了一个 BasicDetails.cshtml 视图(包含 FirstName、LastName 和 Email 等类型),它实际上可以在所有解决方案中使用。编辑器模板在这里似乎很理想,但我的困惑出现了,因为如果我使用 ServiceViewModelOne.cs 并执行 @Html.EditorForModel(),我要么吐出所有 100 种类型,要么使用模板只吐出我想要的BasicDetails.cshtml 通过在 \Views\Shared\EditorTemplates\ServiceViewModelOne.cshtml 创建模板。

现在,我是否可以执行以下操作:

@Html.EditorForModel("BasicDetails")
@Html.EditorForModel("WizardStep2")
@Html.EditorForModel("WizardStep3")

对于我想要制作的每个自定义模板(以及我想要制作的更多模板),都使用相同的 ServiceViewModelOne.cs?如果我是正确的,那么我将具有以下文件夹结构:

  • \View\Shared\EditorTemplates\BasicDetails.cshtml
  • \View\Shared\EditorTemplates\WizardStep2.cshtml
  • \View\Shared\EditorTemplates\WizardStep3.cshtml
  • ...

显然,在每个模板中我都会有相应的

<div class="editor-label">
    @Html.LabelFor(m => m.FirstName)
</div>
<div class="editor-field">
    @Html.EditorFor(m => m.FirstName)
    @Html.ValidationMessageFor(m => m.FirstName)
</div>
...

针对特定于向导中该步骤的所有 HTML 输入(包括整个 HTML 布局)

这是做我想做的事的合适方法,还是我找错了树?

更新: 我考虑过使用 UIHint,但我不确定它是否能完全工作。

我可以在模型级别使用 UIHint:

[UIHint("BasicDetails")]
public class MyModel {}

或在类型级别

public class MyModel
    {
        [UIHint("FirstName")]
        public string FirstName { get; set; }
    }

我可以创建一个 MyModel.cs,然后将其中的一些类型自动映射到 MyViewModelOne.cs、MyViewModelTwo.cs 等。

但是,可以这么说,我想我最终还是会自暴自弃。

假设我有 Type1、Type2、Type3、Type4。 Type1 可以在每个解决方案中使用(保持简单,假设有 4 个解决方案)。 Type2 和 Type3 可用于一种解决方案,但不能用于其他解决方案。假设在另一个解决方案中我可以使用 Type2 和 Type4。

使用 UIHint 或自动映射意味着我必须创建 3 个不同的东西来解决上述问题,如果我需要在另一个解决方案中使用 Type3 和 Type4 怎么办。

我可能会跑题,但这似乎限制了我创建多个排列,这是我希望避免的。

我承认自己没有使用过 AutoMapper,并且正在研究这是否会有所帮助。

【问题讨论】:

    标签: asp.net-mvc-3


    【解决方案1】:

    由于您的问题的复杂性,这有点令人困惑,但我会尝试一下。

    Editor Templates 以两种方式打破惯例 - 文件名需要与模型名称匹配,模板类型需要与模型类型匹配。

    因此,如果您有多个具有不同名称的类,但您想使用一个模板,那么它不会立即奏效。

    我可以看到几个选项。

    1. 在您的模型上使用[UIHint] 来指定模板的名称。
    2. 在您的服务和演示之间创建另一个层,将模型映射到视图模型中,这样视图就不需要关心渲染 100 多个不同的类。您可以使用 AutoMapper 之类的工具轻松完成此操作。

    我强烈建议使用选项 2(如果可能)。再次,不确定我是否理解你的问题。

    【讨论】:

    • 你肯定了解我的困境。我已经更新了我的问题,以考虑您的回复。
    • @REMESQ - 听起来您已经按照编辑的外观对其进行了排序。我很高兴,因为它变得更加混乱。 :)
    【解决方案2】:

    更新(回答) 我想出了如何处理这个问题,如果这对其他人有用,我会发布答案。 就我的目的而言,这对我有很大帮助,并在遵守 DRY(在某种程度上)的同时开辟了许多可能性,因为拥有一个模板比拥有 6 个具有相同字段的文件更好。

    我发布了这个问题,因为我尝试将模板放在 \Views\Shared\EditorTemplates\BasicDetails.cshtml 并且只是返回了我的所有属性(FirstName 等字段),而不是我想要的少数属性(FirstName、LastName , 电子邮件)。如果我有一个模型 BasicDetails.cs(例如),通常将模板放在 \Shared\ 文件夹中是正确的做法。

    阅读埋在Brad Wilson's Post中的cmets,我意识到我应该尝试将模板放入

    \Views{CurrentController}\EditorTemplates\BasicDetails.cshtml。

    工作显示视图和验证错误弹出“必填”字段,向导在单击“下一步”或“提交”后执行其步骤

    重申一下,我用了

    @Html.EditorForModel("BasicDetails")
    

    其中“BasicDetails”是当前控制器中的模板名称。

    【讨论】:

      猜你喜欢
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 2020-05-16
      • 2011-11-01
      相关资源
      最近更新 更多