ASP.NET MVC - 如何实现可重用的用户控件并保持DRY?

时间:2009-12-31 00:36:52

标签: asp.net asp.net-mvc user-controls dry

首先发帖所以请温柔:)

在ASP.NET MVC中创建用户控件时,构造代码的最佳方法是什么,以便调用使用用户控件的视图的控制器不必全部了解控件?我想知道在ASP.NET MVC中使用用户控件时保持DRY的好方法。

请注意,此问题仅适用于需要在回发上进行特殊处理和逻辑的用户控件。我没有问题为用户控件创建漂亮的DRY代码,这些用户控件只能是视图(使用RenderPartial)或需要一些预处理来创建适当的ViewModel(使用RenderAction)。

此外,此问题仅适用于在应用程序中实现可重用控件。我并不担心应用程序之间的可重用性。

举一个具体的例子,假设我想创建一个“快速添加”用户控件,其中包含三个输入字段,名字,姓氏和公司名称以及提交按钮。使用QuickAdd功能时,应执行以下步骤,与控件所在的页面无关:

  1. 验证字段是否为空,如果是,则显示指示符。
  2. 执行查询到存储库以查看公司是否已存在,如果不存在;创造它。
  3. 创建与现有公司或新创建的公司相关联的新联系人
  4. 重新渲染现有页面。如果没有验证错误,用户将再次看到完全相同的页面,否则将显示具有验证错误的同一页面。
  5. 实现DRY的主要问题与调用包含局部视图的视图的所有控制器有关,最终必须有一个Action Method来处理来自Quick Add的表单提交。即使我将用于处理信息的逻辑分解为单独的控制器并从每个其他控制器调用该方法,调用具有可重用控件的视图的每个控制器都必须拥有该知识,这似乎是一种负担。

    我看到的另一个选项是让可重用控件始终提交给特定的操作方法/控制器,但是该控制器无法知道如何为调用该控件的特定控制器重新填充模型。包含可重用控件的视图(在步骤4中)。

    我知道在MVC 2中有关于子控制器的讨论(来自这个问题ASP.NET MVC - Contained User Controls),但由于它还没有,在保持DRY的同时构建代码以实现最大可重用性的最佳方法是什么?

    是否有必须让所有控制器调用使用可重用控件的视图的控制器(具有上述特性),还必须有一个Action方法来处理来自控件的信息?

3 个答案:

答案 0 :(得分:2)

在帖子的最后,你会问“是否有必须拥有所有控制器的替代方案......必须有一个操作方法来处理来自控件的信息

该问题的答案是编写自定义模型绑定器。您的自定义模型绑定器可以负责将传入表单控件中的值填充到所有控制器使用的模型或属性中。通常,您希望将验证与模型绑定分开,但没有理由不能将它们组合在一起。

我强烈建议6 Tips for ASP.NET MVC Model Binding深入讨论该主题以及一些好的参考资料。

答案 1 :(得分:0)

我不确定为什么你说快速添加表单必须在每个使用它的控制器中都有一个动作方法;如果你在Html.BeginForm()中包装快速添加功能; Html.EndForm()组合,你可以让beginform方法指定动作和控制器的名称,所以你只需要一个控制器。

我明白你的来源;这是我一直在考虑的事情。虽然我不知道所有的答案,但我有一些想法供您考虑。每个控制器操作方法都是通过ControllerActionInvoker类调用的,您可以自定义它。此类处理调用所有操作方法,因此您可以在所有或某些操作方法中嵌入可重用代码的某些方面。

查看过滤器,因为您可以使用各种过滤器,或者为实现它的操作方法自定义该过滤器。这样,代码可以在动作方法执行和结果执行之前和之后运行。

对于验证,已经内置了验证组件,这将阻止页面提交...您还可以考虑具有一些其他不错功能的XVAL。 Unity框架是一个IOC容器框架,动态注入可以保持松散耦合和DRY,因为您可以注入各种引用。

另外,你提到了子控制器; MVC预览具有您可能感兴趣的其他功能...例如,它有一个RenderAction方法,可以在另一个动作的视图中呈现动作方法。

希望这有帮助...所以我错过了什么?

答案 2 :(得分:0)

查看RenderAction和RenderPartial。这些是在视图中任意注入公共控件的规范方法。

如果要将数据作为ViewData基础结构的一部分包含在内,请使用RenderPartial。

如果希望数据与ViewData基础架构分离,请使用RenderAction。数据将来自您在RenderAction中指定的控制器方法。

如果你还没有这样做,请查看NerdDinner教程。