【问题标题】:ASP.Net MVC: How do I Reuse Views and Partials With Different Models?ASP.Net MVC:如何使用不同的模型重用视图和部分?
【发布时间】:2014-11-04 20:04:44
【问题描述】:

我需要根据我保存的用户类型显示不同的表单字段。

我有一些用户类型,而一些用户类型具有相同的数据,因此您可以想象以下情况(可能会有更多类型):

  1. TypeA:名称、密码等、LinkedToLegacySystemA、LegacySystemAUserId
  2. TypeB:名称、密码等、LinkedToLegacySystemB、LegacySystemBUserId
  3. TypeC:名称、密码等、LinkedToLegacySystemC、LegacySystemCUserId、LegacySystemCAdminLevel

当我创建一个新用户时,我可能处于这些系统中的任何一个的上下文中,但我确切地知道我连接到哪个系统(每种类型的用户都有一个特定的 CRUD 控制器),但我想分享意见(如果可能)。所以我得到了这个:TypeAUserController、TypeBUserController、TypeCUserController,每个都有自己的 Create、Retrieve、Update 和 Delete Get/Post 操作。

所以基本问题是“如何重用视图以显示为每个用户创建?”

编辑: 为了进一步澄清,每个用户都有共享信息,这是我想分享的观点。迄今为止我提出的想法假设模型之间的差异将被封装在局部视图中,并且每个潜在模型都有自己的视图。因此,我们正在为用户的每个 CRUD 操作查看单个页面级模型,然后为每个封装差异的子模型查看单个子模型。 这不是一个好方法,原因如下。

【问题讨论】:

  • 鉴于您一直含糊不清,这很难说。视图应该是模型的强类型。如果你有不同的模型,你应该有不同的观点。但是,您总是可以拥有一个包含所有这些的视图模型。你可以有一个所有视图模型都继承自的基类,然后使用 EditorTemplates 来呈现特定类型。但是,所有这些都有您需要处理的各种问题。
  • 是的,我为我的头脑风暴添加了我自己的答案。他们符合你的建议,你是对的,他们每个人都有自己的问题:(

标签: asp.net-mvc


【解决方案1】:

潜在的解决方案 1: 将此模型传递给视图

  • 创建用户页面模型
    • BoringModelWithSharedStuff
    • LegacySystemAModel
    • LegacySystemBModel
    • LegacySystemCModel
    • 部分名称

然后在视图中使用部分名称来决定显示哪个部分并选择一个非空模型传递给它。

提交表单时,它会提交到带有自定义模型绑定器的页面,该绑定器会选择正确的模型。

好处:

  • 允许重用父视图
  • 模型中的差异位于不同的部分中

缺点:

  • View 必须找到填充的子模型才能传递给局部
  • 必须传递部分名称,因此必须在控制器中选择路径

【讨论】:

  • 拥有一个需要为每个新旧系统编辑的共享模型似乎是一种糟糕的模式。在添加遗留系统 d 时,必须有一种方法可以使遗留系统 a 到 c 的模型保持不变
【解决方案2】:

可能的解决方案 2:使用视图包。

模型会超级简单:

  • 创建用户页面模型
    • 共享数据模型

然后视图将检查 Viewbag 以获取有关它将加载哪个部分的信息,方法是指定部分名称或提供要打开的视图的枚举。 然后,partial 会将 viewbag 中的项目转换为特定类型。

好处:

  • 允许重用父视图
  • 模型中的差异放在不同的部分中

缺点:

  • 视图必须选择要加载的正确部分
  • Partial 必须转换为其已知类型

【讨论】:

  • 此外,在提交表单时,这将需要一个自定义模型绑定器来选择正确的模型,从而有效地确定再次投射到什么。
【解决方案3】:

可能的解决方案 3:使用标记界面

  • 创建用户页面模型
    • 共享数据模型
    • ILegacyUserDataModel
    • 部分名称

视图根据传递的模型加载一个部分,然后将 ILegacyUserDataModel 传递给部分。然后,partial 将转换为它设计的任何模型。

好处:

  • 允许重用父视图
  • 模型中的差异放在不同的部分中

缺点:

  • 必须传递部分名称,因此必须在控制器中选择路径
  • Partial 必须从接口转换为它所设计的真实类型

【讨论】:

  • 我真的不喜欢使用标记界面的想法,感觉很脏
  • 此外,在提交表单时,这将需要一个自定义模型绑定器来选择正确的模型,从而有效地确定再次投射到什么。
【解决方案4】:

好的,这就是它的实际实现方式......

每个 CRUD 上 GET 的 3 个页面级“显示”模型,每个

  • 创建LegacyUserAModel
    • SharedUserModel 模型(此模型上有数据注释用于验证)
    • LegacyUserAModel(这个有数据注释用于验证)
  • ...
  • 创建LegacyUserCModel
    • ...

然后是意见:

  • CreateLegacyView(使用 CreateLegacyUserAModel,处理创建表单)
    • SharedUserFieldsView(使用 SharedUserModel)
    • LegacyUserFieldsView(使用 LegacyUserAModel)

我们几乎翻转了视图/模型。

缺点

  • 每个 CRUD 操作都需要一个视图和特定模型(4 * n 个 DisplayModel)
  • 每个 CRUD 操作都有一个 POST(老实说,这对我来说很有意义)

优点

  • 无需在任何地方强制转换任何模型,无需在视图中强制转换,也无需在 POST 操作中强制转换

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多