面向初学者的 MVC 应用程序






4.79/5 (48投票s)
引言
如果您是 Web 开发新手,并渴望迈出在模型-视图-控制器(MVC)架构领域的第一步,那么您来对地方了。本文专门为绝对初学者量身定制,是您进入激动人心的 MVC 世界的首次旅程。
在接下来的几分钟里,我们将踏上 MVC 的实践探索之旅,我将引导您创建一个简单的项目。我们的目标是揭开模型、控制器和视图组件之间如何无缝地控制流动的神秘面纱,为您自信地探索更复杂的 MVC 应用打下坚实的基础。
因此,无论您是充满好奇的代码新手,还是只是想回顾一下,让我们一起深入了解并掌握构建 MVC 应用的基础原理。
我们将要涵盖的主题
在本文中,我们将探讨 MVC(模型-视图-控制器)Web 开发中的基本概念。我们将涵盖以下关键主题:
- 理解文件夹结构 - 我们将首先讨论 MVC 项目的基本文件夹结构。
- MVC 如何工作:导航控制流 - 接下来,我们将深入 MVC 的核心——控制流。我们将分解用户请求的处理方式,让您清楚地了解模型、视图和控制器如何协同工作以创建无缝的用户体验。
- MVC 的构建块:控制器、模型和视图 - 最后,我们将向您介绍 MVC 的关键组件——控制器、模型和视图。我们将解释它们的作用并指导您创建它们的过程,确保您为开发自己的 MVC 应用打下坚实的基础。
那么,让我们开始创建一个简单的项目。我们的项目工作描述如下。
我们应用程序的功能
- 启动我们的应用程序后,主页将醒目地显示一个标记为“click”的超链接。当用户单击此超链接时,将立即显示一条消息,并显示一条热情洋溢的“Hello World!!”。
- 更进一步,我们的应用程序将从显示简单消息过渡到展示一系列个人姓名。这个包含人名的列表将醒目地显示,提供更具吸引力和交互性的用户体验。
理解文件夹
当您创建一个项目时,会在项目名称下默认创建一个文件夹结构,可以在解决方案资源管理器中看到。这些文件夹及其相应的内容在组织、构建和运行典型的 MVC 应用程序中起着至关重要的作用。理解它们的用途是使用 Web 开发中的模型-视图-控制器模式的基础步骤。
模型
Model 文件夹用于定义表示应用程序数据的类。这些类可以与数据库交互以检索和操作数据,或者它们可以保存用户通过表单输入的数据,以便稍后更新数据库。换句话说,Model 处理应用程序的数据相关逻辑。
控制器
Controllers 是处理用户交互并根据这些交互执行操作的类。每个控制器都包含称为 Actions 的方法,这些方法响应用户请求并确定如何处理这些请求。这些操作决定了应用程序如何响应用户输入。
视图
Views 文件夹包含应用程序的用户界面组件。视图负责将 Model 中的数据呈现给最终用户。它们使用 Model 中的数据填充 HTML 控件并生成在客户端 Web 浏览器中呈现的内容。本质上,视图处理应用程序的表示和用户界面方面。
App_Start
App_Start 文件夹包含各种应用程序设置和行为的配置类。在您提到的上下文中,它包括 FilterConfig
、RoutesConfig
和 WebApiConfig
等类。RouteConfig
类对于定义用于在应用程序中的不同页面或操作之间导航的 URL 结构特别重要。
例如
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
当然,这里是文本的修订版本,语气更专业,语言更简化。
在此上下文中,MapRoute
是一个扩展方法。它的 url
属性用于定义 URL 的结构。默认情况下,指定的格式按以下顺序排列:{控制器名称}/{操作名称}/{可选参数}。
您可以根据自己的具体要求修改此格式。但是,重要的是要注意这是标准化格式,URL 的第三部分,由 {id}
表示,是可选的。我们将在本文后面更详细地探讨此 id 的使用方式。
控制流
为了方便理解模型-视图-控制器(MVC)中的控制流,我们将从一个简化的图表开始。
- Controller:旅程从控制器开始。在此,接收用户请求并根据这些请求启动操作。控制器充当协调者,决定要采取的具体操作。
- Model(如果需要):根据请求的性质,控制器可能需要与模型进行交互。模型负责处理数据相关操作,这可能包括检索、更新或处理数据。当请求需要数据操作时,会发生这种交互。
- 返回 Controller:与模型交互后,控制权返回到控制器。此阶段涉及根据从模型获得的结果做出决策,或进行进一步处理,可能导致额外的操作。
- View:控制流的最终目的地是视图。视图负责以用户友好的方式呈现由控制器和模型处理的数据。它生成 HTML 等视觉组件,这些组件被发送到用户的浏览器进行显示。
随着我们在文章中不断深入,您将更深入地理解 MVC 架构模式中控制器、视图和模型之间复杂的动态关系。这种基本理解为应对基于 MVC 的 Web 开发的复杂性奠定了坚实的基础。
现在,为了开始构建我们的应用程序,我们需要一个在应用程序启动时显示的首页。此首页包含一个标记为“click”的超链接。在此阶段,我们将实现此功能。
正如您可能还记得从控制流图中,第一步是控制权被定向到控制器。为了确保我们的应用程序按预期运行,控制器的存在至关重要。
创建 MVC 应用程序
我使用了 Visual Studio 2013,但您也可以使用 Visual Studio 2012。在 Visual Studio 中创建一个名为 Sample 的新项目。
- 启动 Visual Studio。
- 转到“文件”并选择“新建”,然后选择“项目”。
- 在左侧面板的“Web”部分下,在 .NET Framework 4.5 下选择“MVC 4 Web Application”。将项目命名为“Sample”并单击“确定”。
- 在模板窗口中,选择“Empty Application”模板。虽然“Internet Application”模板是一个选项,但为简单起见,我们将选择“Empty Application”。
- 选择“Razor”引擎作为您的视图引擎。您可能会想,什么是视图引擎?
- 在 ASP.NET MVC 中,视图引擎充当视图和浏览器之间的中介。它确保来自视图的输出在浏览器中呈现为有效的 HTML。
- 。NET Framework 提供两个视图引擎:“Razor”和“ASPX”。它们在命名空间、文件扩展名和语法方面有所不同。
- Razor 使用 .cshtml(在 C# 中)和 .vbhtml(在 VB 中)扩展名。
- ASPX 对视图使用 .aspx,对用户控件使用 .ascx,对母版页使用 .master。
- 单击“确定”,您的应用程序将被创建。
现在,我们将一步一步地按照“我们应用程序的功能”标题进行。让我们从第一步开始
当我们运行应用程序时,它应该在主页上包含一个名为 click 的超链接。单击超链接后,应显示一条消息,即“Hello World!!”
对于这个初始步骤,我们将专注于创建主页。为了确定使用三个组件(模型、视图、控制器)中的哪个,请考虑主页使用 HTML 元素向用户呈现内容。在这种情况下,创建主页的正确组件是“View”。
创建视图
- 在 Views 文件夹中,创建一个名为 Person 的新文件夹。
- 右键单击 Person 文件夹,选择“添加”,然后在展开的选项中单击“View”。将视图命名为“Home”并单击“确定”。此操作将在 Person 文件夹中添加一个名为 Home.cshtml 的视图,重要的是要注意 Razor 视图引擎视图的扩展名是 .cshtml。
- 在 Home.cshtml 视图中,您会找到 .NET Framework 生成的默认代码。将
<h2></h2>
HTML 元素内的内容替换为以下代码:
@Html.ActionLink("click","Message","Person")
此行代码创建了一个名为 click 的超链接。请注意 @
符号;在 Razor 视图引擎中,它用于包含代码。Html
是一个辅助类,用于创建文本框、标签、超链接等 HTML 控件。为了创建超链接,我们使用 Html
辅助类的 ActionLink
方法。
ActionLink
方法有多个重载,但在这种情况下,我们使用的是第 4 个重载:Html.ActionLink(string linkText, string actionName, string controllerName)
。linkText
设置为click
。actionName
是单击链接时应执行的操作方法的名称;让我们将其命名为Message
。controllerName
是包含Message
操作方法的控制器的名称;我们将将其命名为Person
。
重要提示:多个控制器可能包含同名操作方法。
此 HTML 组件(ActionLink
)将被呈现,但在单击时不会按预期工作,因为我们尚未创建 ActionLink
方法中指定的控制器和操作(即 Person
和 Message
)。
您可能还记得,控制器包含操作。因此,对于我们的应用程序,Person
控制器将包含 Message
操作。为了解决这个问题,让我们开始创建控制器。
创建控制器
- 在解决方案资源管理器中,右键单击 Controller 文件夹。选择“添加”,然后从展开的选项中选择“Controller”。将控制器命名为“Person”。
- 请记住在名称末尾包含“Controller”一词,因此控制器的名称应为
PersonController
。单击“确定”。 - 在
PersonController
中,您会找到一些默认代码,包括一个 Index 操作。删除此方法,因为我们的PersonController
应该有一个Message
操作。让我们来创建它。 - MVC 控制器中的操作是一个方法。在
PersonController
类中,创建一个名为Message
的空方法。目前,将此方法的返回类型保留为 void。 - 我们将定义
Message
操作的功能。我们的目标是让此操作为用户显示“Hello World!!”消息。为了显示此消息,我们需要一个视图。因此,我们将从Message
操作返回一个视图。由于我们将从Message
操作返回某些内容,因此其返回类型不应为 void。 - 视图由
ViewResult
类表示,该类继承自ActionResult
类。因此,Message
操作的返回类型将为ActionResult
。 - 我们的
PersonController
和Message
操作将如下所示:
class PersonController
{
public ActionResult Message()
{
return view();
}
}
操作的返回类型可能会因具体要求而异。例如,在返回 JSON 格式的内容时,返回类型将是“JsonResult”。为了返回视图,我们使用 ActionResult
。Message
操作将返回一个名为 Message
的视图,该视图将包含“Hello World!!”消息。
为了实现这一点,您必须创建另一个与返回它的操作同名的视图,即“Message”。将此视图添加到您添加“Home”视图的同一文件夹中,即 Person 文件夹。
重要提示:在 Views 文件夹中创建的文件夹的名称应与添加这些视图的控制器名称匹配。
为了显示“Hello World”消息,您可以使用像这样的 HTML 标题元素:
<h2>Hello World!!</h2>
除了 Message
操作之外,我们还需要另一个操作,我们称之为“Home”。此操作旨在显示主页。
请记住,根据控制流,第一接触点是控制器,它执行操作。因此,要在我们的应用程序运行时打开带有主页的视图,我们需要一个可以使用控制器操作来实现的操作。
以类似 Message
操作的方式在 PersonController
中创建 Home
操作。它将具有与 Message
操作相同的定义。唯一的区别是它们的名称。
调整路由配置
现在运行您的应用程序,按 Ctrl + F5。您将看到以下页面:
控件未显示我们的主页的原因与 RouteConfig
类有关。当您打开 App_Start 文件夹中的 RouteConfig
类时,您会注意到默认 URL 指定控制器为“Home”,操作为“Index”。但是,在我们的项目中,我们没有名为 Home 的控制器或名为 Index 的操作。此默认 URL 在我们的应用程序运行时执行,但我们希望显示我们的自定义主页。
为了实现这一点,我们需要在 RouteConfig
类中做一些小的更改。具体来说,将控制器设置为 Person
,将操作设置为 Home
。
注意:在控制器参数中,您无需提供完整的 PersonController
。 .NET 框架会自动在您提供的控制器名称后附加“Controller”一词。因此,当您运行应用程序时,它会将 Person
理解为 PersonController
。
此 URL 现在将控制导向 PersonController
,并在其中导向 Home
操作,该操作包含一个 return 语句。
您可能会想,控制权如何知道要返回哪个视图,因为我们在 return 语句中没有明确提供视图的名称?嗯,它会根据操作名称来确定要返回的视图。这就是为什么操作名称和视图名称必须匹配的原因,并且它们位于一个名称与包含这些操作的控制器相匹配的文件夹中。
这就是我们将视图组织在名为 Person 的文件夹中(与控制器名称匹配)的原因。如果还有其他控制器带有不同的视图,我们将为这些视图创建单独的文件夹,每个文件夹都以相应控制器的名称命名。
进行这些调整后,执行应用程序,它应该如预期般工作。
应用程序的流程如下:PersonController -> Home 操作 -> Home 视图 -> Click 超链接 -> PersonController -> Message 操作 -> Message 视图。
此基本流程可以通过将参数传递给操作并使用 RouteConfig
类中定义的 URL 的 id
部分来增强。
避免在视图中硬编码消息
为了使视图中的消息更灵活并避免硬编码,您有几种选择:
1. 将消息作为参数传递
您可以将消息作为参数直接传递给 Message
操作:
public ActionResult Message()
{
return view("Hello World!!");
}
此方法提供了一种直接自定义视图中显示的消息的方法。
2. 将消息作为 URL 中的 id 传递
或者,您可以将消息作为 URL 中的 id 传递。在 Home 视图中,使用 ActionLink
方法将消息作为参数传递:
@Html.ActionLink("click","Message","Person", new { id = "Hello World!!"});
在 Person
控制器的 Message
操作中,将从 ActionLink
方法接收到的参数作为 Message
操作的参数:
public ActionResult Message(string id)
{
return view(id); //pass the received message to view
}
并在视图中,您可以使用模型来显示消息:
@model string
<h2>@Model</h2>
此方法允许您通过更改 URL 来动态更改消息。
3. 直接使用 URL 加载页面
您还可以使用 URL 结构直接加载页面:{controller}/{action}/{id}。在您的情况下,它将是 Person/Message/Hello World!!。
如果您想使用与 id 不同的参数名称(例如,message),则需要更改 RouteConfig
类中的名称:
defaults: new { controller = "Person", action = "Home", message = UrlParameter.Optional }
在此,message 参数被设置为可选。如果您不希望它是可选的,您也可以提供一个默认值。此更改允许您使用不同的参数名称,同时保持所需的功能。
继续前进
与其显示消息,不如现在专注于显示人名列表。过程与我们之前所做的类似。唯一的区别是,我们不会将消息传递给视图,而是传递一个要显示的名字列表。
让我们向主页添加另一个超链接来显示人员列表。您已经知道如何使用 ActionLink
方法创建超链接。将此超链接命名为 List_of_Person。
对于 ActionLink
方法的 actionName
参数,指定当单击超链接时将处理此任务的操作的名称。让我们创建一个专门用于显示人员列表的操作,并将其命名为 ShowPerson
。
@Html.ActionLink( "List_of_Person", "ShowPerson" , "Person" )
为了在单击 List_of_Person 链接时显示人名列表,我们将遵循面向对象原则。为此,我们需要一个类来提供必要的数据。在 MVC 架构中,这些类称为 Models。因此,我们将创建一个名为 Person
的模型类,作为我们的数据源。
数据流序列如下:Controller -> Model(如果需要)-> Controller(再次)-> View -> Controller。
与之前不需要 Models 的情况不同,这里 Model 对于将人名列表提供给 View 至关重要。我们的 Person
模型类将包含两个属性:FirstName
和 LastName
。
此 Model 将使我们能够有效地提供显示人名列表所需的数据。
创建模型
好的,让我们继续创建模型和相应的视图来显示人名列表。
- 在解决方案资源管理器中,右键单击 Models 文件夹,然后选择“添加”->“Class”。
- 将类文件命名为 Person.cs 并单击“Add”按钮。
- 在
Person
类文件中,为名字和姓氏定义两个自动属性:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
这个 Person
类将代表个人及其姓名。
现在,让我们在 PersonController
中创建一个名为 ShowPerson
的操作来显示人员列表。此操作将填充 Person
对象列表,并将其传递给视图。
public ActionResult ShowPerson()
{
List<person> persons = new List<person>()
{
new Person { FirstName = "Sherlock", LastName = "Holmes" },
new Person { FirstName = "James", LastName = "Watson" }
};
return view(persons);
}</person></person>
在 ShowPerson
操作中,我们创建了一个 Person
对象列表,每个对象代表一个具有名字和姓氏的个人。此列表代表将在视图中显示的人员列表。
现在,让我们创建一个将显示人员列表的视图。此视图将接收人员列表作为其模型。
- 右键单击 Views 文件夹中的 Person 文件夹。
- 选择“添加”->“View”。
- 选中创建强类型视图的复选框。
- 从“Model class”下拉列表中,选择“Person (UrlMapping.Models)”。
- 从“Scaffold template”下拉列表中,选择“List”。
- 单击“Add”按钮。
通过这些步骤,将在 Views 文件夹的 Person 文件夹中添加一个名为“ShowPerson”的视图。此视图是强类型的,用于接收 Person
对象列表作为其模型。
您现在已成功创建了用于显示人员列表的模型和关联视图。当您执行 ShowPerson
操作时,它将使用 ShowPerson
视图显示人员列表。
现在修改 ShowPerson
视图如下:
@model IEnumerable<CodeProject.Models.Person>
@{
ViewBag.Title = "ShowPerson";
}
<h2>ShowPerson</h2>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.LastName)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
</tr>
}
</table>
现在,按 Ctrl+F5 运行您的应用程序,它应该如预期般工作。当您通过单击主页上的 List_of_Person 超链接导航到 ShowPerson
操作时,它将使用 ShowPerson
视图显示人员列表。
如果您遇到任何问题或有进一步的问题,请随时寻求帮助。祝贺您创建了您的 MVC 应用程序!
关注点
本文是我对 CodeProject 社区的首次贡献。作为 MVC 架构的新手,在构建我的第一个应用程序时,由于缺乏对初学者友好的资源,我遇到了困难,尤其是在 MVC 在市场上相对较新的那个时候。受此启发,我决定分享我的学习经验和见解。我希望这篇文章能为那些涉足 MVC 开发世界的初学者提供宝贵的资源。如果您有任何反馈或问题,请随时与我联系;我在这里为您提供学习之旅的帮助。