了解模型、视图和控制器 (C#)

作者 :Stephen Walther

对模型、视图和控制器感到困惑? 在本教程中,Stephen Walther 介绍了 ASP.NET MVC 应用程序的不同部分。

本教程简要概述了 ASP.NET MVC 模型、视图和控制器。 换句话说,它解释了 ASP.NET MVC 中的 M、V 和 C。

阅读本教程后,应了解 ASP.NET MVC 应用程序的不同部分如何协同工作。 还应了解 ASP.NET MVC 应用程序的体系结构与 ASP.NET Web Forms 应用程序或 Active Server Pages 应用程序的体系结构有何不同。

示例 ASP.NET MVC 应用程序

用于创建 ASP.NET MVC Web 应用程序的默认 Visual Studio 模板包括一个极其简单的示例应用程序,可用于了解 ASP.NET MVC 应用程序的不同部分。 在本教程中,我们将利用这个简单的应用程序。

通过启动 Visual Studio 2008 并选择菜单选项“文件”、“新建项目” (请参阅图 1) ,使用 MVC 模板创建新的 ASP.NET MVC 应用程序。 在“新建项目”对话框中,在“项目类型 (Visual Basic 或 C#) ”下选择喜欢的编程语言,然后在“模板”下选择 “ASP.NET MVC Web 应用程序 ”。 单击“确定”按钮。

“新建项目”对话框

图 01:“新建项目”对话框 (单击以查看全尺寸图像)

创建新的 ASP.NET MVC 应用程序时,将显示“ 创建单元测试项目 ”对话框, (请参阅图 2) 。 通过此对话框,可以在解决方案中创建单独的项目,以测试 ASP.NET MVC 应用程序。 选择“ 否,不要创建单元测试项目 ”选项,然后单击“ 确定 ”按钮。

“创建单元测试”对话框

图 02:“创建单元测试”对话框 (单击以查看全尺寸图像)

创建新 ASP.NET MVC 应用程序后。 你将在解决方案资源管理器窗口中看到多个文件夹和文件。 具体而言,你将看到三个名为“模型”、“视图”和“控制器”的文件夹。 正如你可能从文件夹名称中猜到的那样,这些文件夹包含用于实现模型、视图和控制器的文件。

如果展开 Controllers 文件夹,应会看到名为 AccountController.cs 的文件和名为 HomeController.cs 的文件。 如果展开“视图”文件夹,应会看到三个名为“帐户”、“主页”和“共享”的子文件夹。 如果展开“主页”文件夹,将看到名为 About.aspx 和 Index.aspx 的另外两个文件, (请参阅图 3) 。 这些文件构成默认 ASP.NET MVC 模板中包含的示例应用程序。

解决方案资源管理器窗口

图 03:解决方案资源管理器窗口 (单击以查看全尺寸图像)

可以通过选择菜单选项 “调试”“开始调试”来运行示例应用程序。 或者,可以按 F5 键。

首次运行 ASP.NET 应用程序时,会出现图 4 中的对话框,建议你启用调试模式。 单击“确定”按钮,应用程序将运行。

“未启用调试”对话框

图 04:“未启用调试”对话框 (单击以查看全尺寸图像)

运行 ASP.NET MVC 应用程序时,Visual Studio 会在 Web 浏览器中启动该应用程序。 示例应用程序仅包含两页:“索引”页和“关于”页。 应用程序首次启动时,将显示“索引”页, (请参阅图 5) 。 可以通过单击应用程序右上角的菜单链接导航到“关于”页。

索引页

图 05:索引页 (单击以查看全尺寸图像)

请注意浏览器地址栏中的 URL。 例如,单击“关于”菜单链接时,浏览器地址栏中的 URL 将更改为 /Home/About

如果关闭浏览器窗口并返回到 Visual Studio,将无法找到路径为“主页/关于”的文件。 文件不存在。 那么如何做好这一点呢?

URL 不等于页面

生成传统的 ASP.NET Web Forms 应用程序或 Active Server Pages 应用程序时,URL 和页面之间存在一对一的对应关系。 如果从服务器请求名为 SomePage.aspx 的页面,则磁盘上最好有一个名为 SomePage.aspx 的页面。 如果 SomePage.aspx 文件不存在,则会收到一个丑陋的 404 - 找不到页面 错误。

相反,生成 ASP.NET MVC 应用程序时,在浏览器地址栏中键入的 URL 与在应用程序中找到的文件之间没有对应关系。 在 ASP.NET MVC 应用程序中,URL 对应于控制器操作,而不是磁盘上的页面。

在传统的 ASP.NET 或 ASP 应用程序中,浏览器请求映射到页面。 相比之下,在 ASP.NET MVC 应用程序中,浏览器请求映射到控制器操作。 ASP.NET Web Forms应用程序以内容为中心。 相比之下,ASP.NET MVC 应用程序以应用程序逻辑为中心。

了解 ASP.NET 路由

浏览器请求通过名为“ ASP.NET 路由”的 ASP.NET 框架的功能映射到控制器操作。 ASP.NET 路由由 ASP.NET MVC 框架用于将传入的请求 路由 到控制器操作。

ASP.NET 路由使用路由表来处理传入请求。 此路由表是在 Web 应用程序首次启动时创建的。 路由表在 Global.asax 文件中设置。 默认的 MVC Global.asax 文件包含在清单 1 中。

清单 1 - Global.asax

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

namespace MvcApplication1
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit https://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

当 ASP.NET 应用程序首次启动时,将调用 Application_Start () 方法。 在清单 1 中,此方法调用 RegisterRoutes () 方法,RegisterRoutes () 方法创建默认路由表。

默认路由表由一个路由组成。 此默认路由将所有传入请求拆分为三个段, (URL 段是正斜杠) 之间的任何内容。 第一个段映射到控制器名称,第二个段映射到操作名称,最后一个段映射到传递给名为 Id 的操作的参数。

以下列 URL 为例:

/Product/Details/3

此 URL 分析为三个参数,如下所示:

控制器 = Product

操作 = 详细信息

ID = 3

Global.asax 文件中定义的默认路由包括所有三个参数的默认值。 默认控制器为 Home,默认操作为 Index,默认 ID 为空字符串。 考虑到这些默认值,请考虑如何分析以下 URL:

/Employee

此 URL 分析为三个参数,如下所示:

控制器 = Employee

操作 = Index

Id =

最后,如果打开 ASP.NET MVC 应用程序而不提供任何 URL (例如, http://localhost) 则按如下所示分析 URL:

控制器 = 主页

操作 = Index

Id =

请求将路由到 HomeController 类上的 Index () 操作。

了解控制器

控制器负责控制用户与 MVC 应用程序交互的方式。 控制器包含 ASP.NET MVC 应用程序的流控制逻辑。 控制器确定在用户发出浏览器请求时要发送回用户的响应。

控制器只是类 (例如 Visual Basic 或 C# 类) 。 示例 ASP.NET MVC 应用程序包含一个名为 HomeController.cs 的控制器,该控制器位于 Controllers 文件夹中。 HomeController.cs 文件的内容在清单 2 中重现。

清单 2 - HomeController.cs

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

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Title"] = "Home Page";
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult About()
        {
            ViewData["Title"] = "About Page";

            return View();
        }
    }
}

请注意,HomeController 有两个名为 Index () 和 About () 的方法。 这两种方法对应于控制器公开的两个操作。 URL /Home/Index 调用 HomeController.Index () 方法,URL /Home/About 调用 HomeController.About () 方法。

控制器中的任何公共方法都作为控制器操作公开。 你需要小心这一点。 这意味着,任何有权访问 Internet 的人都可以通过在浏览器中输入正确的 URL 来调用控制器中包含的任何公共方法。

了解视图

HomeController 类公开的两个控制器操作 Index () 和 About () 都返回视图。 视图包含发送到浏览器的 HTML 标记和内容。 使用 ASP.NET MVC 应用程序时,视图等效于页面。

必须在正确的位置创建视图。 HomeController.Index () 操作返回位于以下路径的视图:

\Views\Home\Index.aspx

HomeController.About () 操作返回位于以下路径的视图:

\Views\Home\About.aspx

通常,如果要返回控制器操作的视图,则需要在 Views 文件夹中创建一个与控制器同名的子文件夹。 在 子文件夹中,必须创建一个与控制器操作同名的 .aspx 文件。

清单 3 中的 文件包含 About.aspx 视图。

列表 3 - About.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2>About</h2>
    <p>
        Put content here.
    </p>
</asp:Content>

如果忽略清单 3 中的第一行,则视图的其余大部分由标准 HTML 组成。 可以通过在此处输入所需的任何 HTML 来修改视图的内容。

视图与 Active Server Pages 或 ASP.NET Web Forms 中的页面非常相似。 视图可以包含 HTML 内容和脚本。 可以使用喜欢的 .NET 编程语言 (编写脚本,例如 C# 或 Visual Basic .NET) 。 使用脚本显示动态内容,例如数据库数据。

了解模型

我们讨论了控制器,并讨论了观点。 最后一个需要讨论的主题是模型。 什么是 MVC 模型?

MVC 模型包含视图或控制器中不包含的所有应用程序逻辑。 该模型应包含所有应用程序业务逻辑、验证逻辑和数据库访问逻辑。 例如,如果使用 Microsoft 实体框架访问数据库,则将 (Models 文件夹中的 .edmx 文件) 创建实体框架类。

视图应仅包含与生成用户界面相关的逻辑。 控制器应仅包含返回正确视图或将用户重定向到另一个操作所需的最小逻辑, (流控制) 。 其他所有内容都应包含在模型中。

一般来说,你应该努力寻找胖模特和瘦控制器。 控制器方法应仅包含几行代码。 如果控制器操作变得太胖,则应考虑将逻辑移出到 Models 文件夹中的新类。

总结

本教程简要概述了 ASP.NET MVC Web 应用程序的不同部分。 你了解了 ASP.NET 路由如何将传入的浏览器请求映射到特定控制器操作。 你了解了控制器如何协调视图返回到浏览器的方式。 最后,你了解了模型如何包含应用程序业务、验证和数据库访问逻辑。