ASP.NET MVC:用户控件的良好替代?

3Da*_*ave 11 asp.net-mvc user-controls

在使用ASP.NET webforms时,我发现用户控件非常有用.通过使用标记封装显示控件所需的代码,可重用组件的创建非常简单且非常非常有用.

虽然MVC提供了方便的关注点分离,但这似乎打破了封装(即,您可以在不添加或使用其支持代码的情况下添加控件,从而导致运行时错误).每次我向视图添加控件时都必须修改控制器,这似乎是我要集成关注点,而不是将它们分开.我宁愿打破纯粹的MVC意识形态,也不愿放弃可重复使用的打包控件的好处.

我需要能够在整个站点中包含类似于webforms用户控件的组件,但不能包含整个站点,而不是属于母版页的级别.这些组件应该有自己的代码,而不仅仅是标记(与业务层交互),如果页面控制器不需要知道控件,那将是很好的.由于MVC用户控件没有代码隐藏,我看不到这样做的好方法.

最后更新 ,一个很好的(并且,回想起来,很明显)实现这一目标的方法.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace K.ObjectModel.Controls
{
    public class TestControl : ViewUserControl
    {
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            writer.Write("Hello World");
            base.Render(writer);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

创建一个继承的新类 ViewUserControl

覆盖.Render()如上所示的方法.

通过其关联的ASCX注册控件,就像在webForm中一样:

<%@ Register TagName="tn" TagPrefix="k" Src="~/Views/Navigation/LeftBar.ascx"%>

在您需要的任何视图或母版页中使用相应的标记:

<k:tn runat="server"/>

确保您的.ascx继承了您的新控件:

<%@ Control Language="C#" Inherits="K.ObjectModel.Controls.TestControl" %>

瞧,你已经开始运转了.这是使用ASP.NET MVC 2,VS 2010和.NET 4.0进行测试的.

您的自定义标记引用ascx部分视图,该视图继承自TestControl类.然后控件覆盖该Render()方法,该方法被调用以呈现视图,使您可以完全控制从标记到输出的过程.

使用这种方法和调用Html.RenderPartial()或"Html.RenderAction()" 之间的区别是将控件添加到视图中是使用类似webforms的标记,这不仅对设计人员来说更舒适,而且使他们不必了解控制器名称和方法.控件类的名称与ASCX隔离,也可以更容易地将它们放入程序集中,并在不同的项目中重用它们.

有些人可能会说这违反了SoC,但我相信这种方法在功能上等同于将部分视图和控制器绑在一起,同时保持干净的标记.然而,应该清楚的是,开发人员仍然只能在控制中保留与表示相关的逻辑.业务和数据访问逻辑仍然属于它们各自的层.

Jus*_*ner 5

我在这里有点困惑.

首先,与用户控件等效的.NET MVC是部分视图.部分视图是将常见视图功能封装在单个位置的便捷方式.然后,您可以从另一个视图内部调用部分视图.

其次,修改View并不意味着修改控制器.如果您需要仅因为View更改(而不是基础数据)而对两者进行更改,那么就会出现代码问题.


Joh*_*ell 4

乍一看,人们很容易认为 MVC 不具备可重用组件的功能。

一旦您了解了 ASP.NET MVC,您就会发现有多种技术可用于创建丰富的控件和组件,并且封装 MVC 的各个方面都遵循 与封装 WebForms 应用程序相同的途径。

我认为您所做的只是查看 MVC 的视图方面,而不是如何将所有底层封装MC绑定在一起。部分视图、渲染操作/部分只是 MVC 底层组件功能的一小部分。幕后还有更多的财富。