65.9K
CodeProject 正在变化。 阅读更多。
Home

面向初学者的 MVC 应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (48投票s)

2014年8月19日

CPOL

16分钟阅读

viewsIcon

172104

downloadIcon

4043

引言

如果您是 Web 开发新手,并渴望迈出在模型-视图-控制器(MVC)架构领域的第一步,那么您来对地方了。本文专门为绝对初学者量身定制,是您进入激动人心的 MVC 世界的首次旅程。

在接下来的几分钟里,我们将踏上 MVC 的实践探索之旅,我将引导您创建一个简单的项目。我们的目标是揭开模型、控制器和视图组件之间如何无缝地控制流动的神秘面纱,为您自信地探索更复杂的 MVC 应用打下坚实的基础。

因此,无论您是充满好奇的代码新手,还是只是想回顾一下,让我们一起深入了解并掌握构建 MVC 应用的基础原理。

我们将要涵盖的主题

在本文中,我们将探讨 MVC(模型-视图-控制器)Web 开发中的基本概念。我们将涵盖以下关键主题:

  1. 理解文件夹结构 - 我们将首先讨论 MVC 项目的基本文件夹结构。 
  2. MVC 如何工作:导航控制流 - 接下来,我们将深入 MVC 的核心——控制流。我们将分解用户请求的处理方式,让您清楚地了解模型、视图和控制器如何协同工作以创建无缝的用户体验。
  3. MVC 的构建块:控制器、模型和视图 - 最后,我们将向您介绍 MVC 的关键组件——控制器、模型和视图。我们将解释它们的作用并指导您创建它们的过程,确保您为开发自己的 MVC 应用打下坚实的基础。

那么,让我们开始创建一个简单的项目。我们的项目工作描述如下。

我们应用程序的功能

  1. 启动我们的应用程序后,主页将醒目地显示一个标记为“click”的超链接。当用户单击此超链接时,将立即显示一条消息,并显示一条热情洋溢的“Hello World!!”。
  2. 更进一步,我们的应用程序将从显示简单消息过渡到展示一系列个人姓名。这个包含人名的列表将醒目地显示,提供更具吸引力和交互性的用户体验。

理解文件夹

当您创建一个项目时,会在项目名称下默认创建一个文件夹结构,可以在解决方案资源管理器中看到。这些文件夹及其相应的内容在组织、构建和运行典型的 MVC 应用程序中起着至关重要的作用。理解它们的用途是使用 Web 开发中的模型-视图-控制器模式的基础步骤。

模型

Model 文件夹用于定义表示应用程序数据的类。这些类可以与数据库交互以检索和操作数据,或者它们可以保存用户通过表单输入的数据,以便稍后更新数据库。换句话说,Model 处理应用程序的数据相关逻辑。

控制器

Controllers 是处理用户交互并根据这些交互执行操作的类。每个控制器都包含称为 Actions 的方法,这些方法响应用户请求并确定如何处理这些请求。这些操作决定了应用程序如何响应用户输入。

视图

Views 文件夹包含应用程序的用户界面组件。视图负责将 Model 中的数据呈现给最终用户。它们使用 Model 中的数据填充 HTML 控件并生成在客户端 Web 浏览器中呈现的内容。本质上,视图处理应用程序的表示和用户界面方面。

App_Start

App_Start 文件夹包含各种应用程序设置和行为的配置类。在您提到的上下文中,它包括 FilterConfigRoutesConfigWebApiConfig 等类。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)中的控制流,我们将从一个简化的图表开始。 

  1. Controller:旅程从控制器开始。在此,接收用户请求并根据这些请求启动操作。控制器充当协调者,决定要采取的具体操作。
  2. Model(如果需要):根据请求的性质,控制器可能需要与模型进行交互。模型负责处理数据相关操作,这可能包括检索、更新或处理数据。当请求需要数据操作时,会发生这种交互。
  3. 返回 Controller:与模型交互后,控制权返回到控制器。此阶段涉及根据从模型获得的结果做出决策,或进行进一步处理,可能导致额外的操作。
  4. View:控制流的最终目的地是视图。视图负责以用户友好的方式呈现由控制器和模型处理的数据。它生成 HTML 等视觉组件,这些组件被发送到用户的浏览器进行显示。

随着我们在文章中不断深入,您将更深入地理解 MVC 架构模式中控制器、视图和模型之间复杂的动态关系。这种基本理解为应对基于 MVC 的 Web 开发的复杂性奠定了坚实的基础。

现在,为了开始构建我们的应用程序,我们需要一个在应用程序启动时显示的首页。此首页包含一个标记为“click”的超链接。在此阶段,我们将实现此功能。

正如您可能还记得从控制流图中,第一步是控制权被定向到控制器。为了确保我们的应用程序按预期运行,控制器的存在至关重要。

创建 MVC 应用程序

我使用了 Visual Studio 2013,但您也可以使用 Visual Studio 2012。在 Visual Studio 中创建一个名为 Sample 的新项目。

  1. 启动 Visual Studio。
  2. 转到“文件”并选择“新建”,然后选择“项目”。
  3. 在左侧面板的“Web”部分下,在 .NET Framework 4.5 下选择“MVC 4 Web Application”。将项目命名为“Sample”并单击“确定”。
  4. 在模板窗口中,选择“Empty Application”模板。虽然“Internet Application”模板是一个选项,但为简单起见,我们将选择“Empty Application”。
  5. 选择“Razor”引擎作为您的视图引擎。您可能会想,什么是视图引擎?
    • 在 ASP.NET MVC 中,视图引擎充当视图和浏览器之间的中介。它确保来自视图的输出在浏览器中呈现为有效的 HTML。
    • 。NET Framework 提供两个视图引擎:“Razor”和“ASPX”。它们在命名空间、文件扩展名和语法方面有所不同。
      • Razor 使用 .cshtml(在 C# 中)和 .vbhtml(在 VB 中)扩展名。
      • ASPX 对视图使用 .aspx,对用户控件使用 .ascx,对母版页使用 .master
  6. 单击“确定”,您的应用程序将被创建。

现在,我们将一步一步地按照“我们应用程序的功能”标题进行。让我们从第一步开始

当我们运行应用程序时,它应该在主页上包含一个名为 click 的超链接。单击超链接后,应显示一条消息,即“Hello World!!”

对于这个初始步骤,我们将专注于创建主页。为了确定使用三个组件(模型、视图、控制器)中的哪个,请考虑主页使用 HTML 元素向用户呈现内容。在这种情况下,创建主页的正确组件是“View”。

创建视图

  1. Views 文件夹中,创建一个名为 Person 的新文件夹。
  2. 右键单击 Person 文件夹,选择“添加”,然后在展开的选项中单击“View”。将视图命名为“Home”并单击“确定”。此操作将在 Person 文件夹中添加一个名为 Home.cshtml 的视图,重要的是要注意 Razor 视图引擎视图的扩展名是 .cshtml
  3. 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 方法中指定的控制器和操作(即 PersonMessage)。

您可能还记得,控制器包含操作。因此,对于我们的应用程序,Person 控制器将包含 Message 操作。为了解决这个问题,让我们开始创建控制器。

创建控制器

  1. 在解决方案资源管理器中,右键单击 Controller 文件夹。选择“添加”,然后从展开的选项中选择“Controller”。将控制器命名为“Person”。
  2. 请记住在名称末尾包含“Controller”一词,因此控制器的名称应为 PersonController。单击“确定”。
  3. PersonController 中,您会找到一些默认代码,包括一个 Index 操作。删除此方法,因为我们的 PersonController 应该有一个 Message 操作。让我们来创建它。
  4. MVC 控制器中的操作是一个方法。在 PersonController 类中,创建一个名为 Message 的空方法。目前,将此方法的返回类型保留为 void。
  5. 我们将定义 Message 操作的功能。我们的目标是让此操作为用户显示“Hello World!!”消息。为了显示此消息,我们需要一个视图。因此,我们将从 Message 操作返回一个视图。由于我们将从 Message 操作返回某些内容,因此其返回类型不应为 void。
  6. 视图由 ViewResult 类表示,该类继承自 ActionResult 类。因此,Message 操作的返回类型将为 ActionResult
  7. 我们的 PersonControllerMessage 操作将如下所示:
class PersonController
{
     public ActionResult Message()
     {
          return view();
     }
}

操作的返回类型可能会因具体要求而异。例如,在返回 JSON 格式的内容时,返回类型将是“JsonResult”。为了返回视图,我们使用 ActionResultMessage 操作将返回一个名为 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 模型类将包含两个属性:FirstNameLastName

此 Model 将使我们能够有效地提供显示人名列表所需的数据。

创建模型

好的,让我们继续创建模型和相应的视图来显示人名列表。

  1. 在解决方案资源管理器中,右键单击 Models 文件夹,然后选择“添加”->“Class”。
  2. 将类文件命名为 Person.cs 并单击“Add”按钮。
  3. 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 对象列表,每个对象代表一个具有名字和姓氏的个人。此列表代表将在视图中显示的人员列表。

现在,让我们创建一个将显示人员列表的视图。此视图将接收人员列表作为其模型。

  1. 右键单击 Views 文件夹中的 Person 文件夹。
  2. 选择“添加”->“View”。
  3. 选中创建强类型视图的复选框。
  4. 从“Model class”下拉列表中,选择“Person (UrlMapping.Models)”。
  5. 从“Scaffold template”下拉列表中,选择“List”。
  6. 单击“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 开发世界的初学者提供宝贵的资源。如果您有任何反馈或问题,请随时与我联系;我在这里为您提供学习之旅的帮助。

© . All rights reserved.