【问题标题】:What is the unit of reusability in .NET MVC apps?.NET MVC 应用程序中的可重用性单位是什么?
【发布时间】:2014-05-22 09:56:45
【问题描述】:

在传统的 ASP.NET Web 窗体应用程序中,UserControls 是封装功能以使其可以重用的好方法。但是,UserControl 不太适合 MVC 模型。他们经常大量使用 ViewState,并且模糊了 MVC 提倡的关注点分离。

我的问题是,您如何最好地捆绑一个功能以便在 MVC 应用程序之间共享它?

例如,考虑一个从/到日期选择器 UserControl:

  • 允许用户选择两个日期,或者使用 javascript 覆盖,或者在单独的字段中输入日、月和年
  • 可以配置为默认为今天和明天的日期或开发人员选择的日期
  • 验证用户返回的日期以确保开始日期早于结束日期
  • 公开可以通过代码隐藏访问的 From 和 To 属性

我如何最好地在 .NET MVC 中构建这样的东西以便我可以轻松地重用它?

请注意,要完全模拟用户控件的功能,MVC 组件必须管理提交的表单数据和验证——而不仅仅是演示。

【问题讨论】:

    标签: asp.net asp.net-mvc


    【解决方案1】:

    总的来说,我同意用户控件在封装 UI 内容方面很好,但我认为 MVC 并没有真正改变太多。如果我没记错的话,在经典的 Asp.net 项目中重用用户控件是一种痛苦,而且从来都不是真正创建可重用组件的最佳方式。您为经典 ASP.net 购买的大多数 UI 工具包都没有为您提供用户控件,它们基本上为您提供了服务器控件和 javascript 控件。

    在您的示例中,我可能会创建或找到一个 jquery(或您选择的框架)插件,该插件可以在客户端执行您想要的操作。您还可以围绕它构建一个 C# 包装器,类似于 Telerik 对一些 jquery UI 控件所做的。我确实认为,code-behind 甚至 viewstate 这个词都会从你的词汇表中消失,你越深入MVC。

    如果您查看针对 MVC 的开源项目,您会得到关于您应该做什么的答案。

    • MVC Contrib 应用程序通过创建扩展方法和帮助程序添加了许多功能。他们的网格控件是创建可跨项目使用的可重用组件的典型方式

    • Telerik,创建了一些包装 jquery 控件并进行资产管理的扩展。

    • 最后,我认为,如果您展望未来,MVC 有 areas,如果我理解正确的话,您可以将项目拆分为多个较小的项目。

    【讨论】:

    • 首先,可以在 web 表单中为不使用它的控件禁用 ViewState。说“如果我记得正确地在经典 Asp.net 项目中重用用户控件是一种痛苦,而且从来都不是真正创建可重用组件的最佳方式”,这是绝对不正确的。用户控件是单个应用程序可重用性的理想选择,而自定义服务器控件适用于多个应用程序的可重用性。就可重用性而言,Web 表单是巨大的,因此不应低估它们。
    • 更不用说,当您正确编码这些可重用组件时,您的编码将在您构建库(或购买库并扩展它)时变得更容易和更快。我是唯一一个认为可重用性在这里很重要的人吗?人们不应该去寻找这个应用程序和那个应用程序......我们需要保持一致,如果你有一半的网站在 MVC 中,一半在 Web 表单中,给你更多的权力和一点点小遗憾。
    【解决方案2】:

    除了已经建议的内容,ASP.NET MVC v2 将具有通用模板化输入控件,请参阅here。您可以阅读其他人如何使用类似技术,例如,here

    我们有 恰好 1 个方法调用用于生成 表单元素,“Html.InputFor”。作为 “InputFor”的一部分,它检查 一个输入规范,它收集 PropertyInfo、任何属性、 类型,调用的任何修饰符,以及 选择合适的 InputBuilder。 调用 InputFor(p => p.Id) 并且 Id 是 图形用户界面?这会创建一个隐藏的输入 元素。调用 InputFor(p => p.Customer.Address)和地址是一个 复杂类型?那寻找一个 部分同名的类型

    【讨论】:

      【解决方案3】:

      在考虑了其他人的有用答案后,我将尝试回答我自己的问题。

      在我看来,在 MVC 中模拟 UserControl 的主要困难在于它们横切了 MVC 旨在分离的关注点。在我的示例中,从/到日期选择器 UserControl 包含了模型、视图、控制和交互的元素。 UserControls 将所有这些捆绑在一起的能力正是它们不能很好地融入 MVC 的原因。

      这意味着在 MVC 中创建一个伪 UserControl 需要四个单独的部分:

      • Model 类 - 在本例中为 Interval 类或类似的类
      • 知道如何将模型呈现为 HTML 的 PartialView
      • 在 PartialView 的 HTML 之上分层交互的 jQuery 脚本
      • 可以将 postdata 反序列化为 Model 类的实例的 ModelBinder。

      ModelBinder 很重要,因为它处理从用户返回的数据。没有它,每个想要在其任何视图中显示到/从日期选择器的控制器都必须知道如何组装六个 postdata 字段 - 以及如果它们无效或丢失了如何处理。

      【讨论】:

        【解决方案4】:

        我能想到的两种方法。局部视图虽然这并不能真正从应用程序转移到应用程序,因为您正在移动 ascx 文件。不是很大的痛苦,但不是我的口味。

        我更喜欢使用 WebControls。它们在 mvc 中非常简单,您需要做的就是在项目中引用库,也可能在您的配置文件中引用,然后就可以了。

        【讨论】:

          【解决方案5】:

          我认为有些答案错过了控件的回发功能。您可以处理的一种方法是在渲染局部视图时通过 ViewData 传递任何通用信息。然后它可以回发到它自己的控件,而后者又可以重定向到 UrlReferrer。

          它有点混乱,使用 UrlReferrer 会带来安全风险。但这是解决问题的一种方法

          【讨论】:

          • 是的,我认为考虑用户返回的数据很重要。理想情况下,更广泛的应用程序不会暴露于如何从发布数据中组装日期。
          【解决方案6】:

          您可以创建一个jQuery plugin

          【讨论】:

            【解决方案7】:

            作为 ASP.NET Webforms 中提供的用户控件,MVC 提供了很多方法来制作可以在其他应用程序中重用的控件和代码。

            使用部分代码如果您的部分代码有一些 C# 逻辑并使用 Razor/aspx 代码呈现 html,那么最好将它们保存在 razor 文件中。

            将 JavaScript 功能编写为插件下次当您在其他应用程序上工作时,只需打开此解决方案复制并修改它。编写可用作插件的 JavaScript 代码可能需要更多的头脑风暴。

            将代码编写为单独的 C# 库如果某些代码对于您制作的每个应用程序来说都太常见了。例如,您编写了一个成员身份验证系统或一些在每个应用程序中使用的全局函数 (C#)然后将它们保存在一个单独的解决方案中,以便将来在您尝试制作新应用时可以在您制作的其他应用中使用。

            【讨论】:

              猜你喜欢
              • 2022-01-12
              • 2010-11-08
              • 2017-09-07
              • 1970-01-01
              • 2014-02-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多