15.3 MVC 4项目元素详解
15.2节创建了第一个MVC 4项目,并在浏览器中进行了测试。在创建过程中会有很多选项,同时VS 2012会生成相应的框架和文件。本节以前面创建的MVC项目为例,详细介绍MVC 4项目的重要组成元素。
15.3.1 MVC 4应用程序目录结构
在使用VS 2014创建一个使用基本模板的MVC 4应用程序之后,将会自动向这个应用程序中生成很多文件和目录。如图15-5所示为默认的目录结构。
图15-5 MVC应用程序目录结构
默认生成9个顶级目录,具体说明如表15-1所示。
表15-1 MVC应用程序目录及说明
如表15-1所示,默认的目录结构提供了一个很好的目录约定,使得应用程序文件的管理非常清晰。但是ASP.NET MVC 4并不强制要求使用上面那些目录结构。例如,在大型应用程序中开发人员通常把数据和业务逻辑等放到单独的一个项目中。
15.3.2 MVC 4的约定优于配置
在默认情况下,ASP.NET MVC 4应用程序对约定的依赖性很强。这样就避免了开发人员配置具体化约定可以设置的项。例如,当解析视图模板时,ASP.NET MVC 4采用一种基于约定的目录命名结构。这个约定可以使在Controller类中引用视图引擎时省略位置路径信息。默认情况下,ASP.NET MVC 4会在应用程序\Views\控制器名称\目录下查找视图模板文件。
所谓约定优于配置是指“已经掌握如何创建一个Web应用程序,现在将以往积累的经验应用于框架中,从而避免开发时针对每一项的配置工作。”
在ASP.NET MVC 4的如下三个核心目录中就使用了约定优于配置规则。
(1)Controllers目录。
(2)Models目录。
(3)Views目录。
根据MVC 4的目录结构以及约定优于配置原则,可以很容易地预测到程序结构:
(1)每一个控制器类的名称都以Controller结束,例如ProductController、HomeController等,这些控制器类都存放在Controllers目录中。
(2)应用程序中的所有视图都存放在Views下的一个单独目录中。
(3)控制器使用的视图是在Views主目录的一个子目录中,该子目录是根据控制器名称来命名的。例如,Product控制器使用的视图放在/Views/Product目录中。
(4)所有可重用的UI元素都位于一个相似的结构中,共享目录Views/Shared用于存放其他视图。
15.3.3 MVC 4项目中的模型、视图与控制器
在构建传统的ASP.NET Web Forms应用程序时,URL和页面是一一对应的。如果从服务器上请求名称为Index.aspx的页面,则对应网站目录下名为Inex.aspx的文件。如果Index.aspx文件不存在,则将出现“404 - Page Not Found”错误。
相反,在构建ASP.NET MVC 4应用程序时,在浏览器地址栏中输入的URL和应用程序中的文件不存在对应关系。在ASP.NET MVC应用程序中,URL对应的是控制器操作,而不是网站下的文件。
还有,在传统的ASP.NET应用程序中,浏览器请求是映射到页面上的。在ASP.NET MVC应用程序中,浏览器请求是映射到控制器操作的。ASP.NET Web Forms应用程序关注的是内容,而ASP.NET MVC应用程序关注的是应用程序逻辑。
1.控制器
控制器负责控制用户与MVC应用程序的交互方式。控制器决定在用户发出浏览器请求时向用户发送什么样的响应。
控制器只是一个类。ASP.NET MVC示例应用程序包括一个名称为HomeController.cs的控制器,该控制器位于Controllers文件夹内。
HomeController.cs的内容如下所示。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcApplication.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。"; return View(); } public ActionResult About() { ViewBag.Message = "你的应用程序说明页。"; return View(); } public ActionResult Contact() { ViewBag.Message = "你的联系方式页。"; return View(); } } }
从以上代码中看到,HomeController有三个方法,名称分别为Index()、About()和Contact()。这三个方法对应于控制器公开的三个操作。URL“/Home/Index”调用HomeController.Index()方法,URL“/Home/About”调用HomeController.About()方法,而URL“/Home/Contact”调用HomeController.Contact()方法。
控制器中的任何公共方法都作为控制器操作被公开。这意味着通过向浏览器输入正确的URL来访问Internet的任何人都可以激活包含在控制器中的任何公共方法。
2.视图
HomeController类的三个公共控制器方法都返回了一个视图。视图包括发送到浏览器的HTML标记和内容。在使用ASP.NET MVC应用程序时,视图就等于页面。
因此,必须在正确的位置创建视图。HomeController.Index()操作返回位于以下路径的视图。
\Views\Home\Index.aspx
HomeController.About()操作返回位于以下路径的视图。
\Views\Home\About.aspx
总之,如果要为控制器操作返回视图,则需要在Views文件夹中使用与控制器相同的名称创建子文件夹。在子文件夹中,必须创建与控制器操作名称相同的.aspx文件。
如下所示为About.aspx视图文件中所包含的代码。
@{ ViewBag.Title = "关于"; } <hgroup class="title"> <h1>@ViewBag.Title.</h1> <h2>@ViewBag.Message</h2> </hgroup> <article> <p>使用此区域可提供附加信息。</p> <p>使用此区域可提供附加信息。</p> <p>使用此区域可提供附加信息。</p> </article> <aside> <h3>副标题</h3> <p> 使用此区域可提供附加信息。 </p> <ul> <li>@Html.ActionLink("主页", "Index", "Home")</li> <li>@Html.ActionLink("关于", "About", "Home")</li> <li>@Html.ActionLink("联系方式", "Contact", "Home")</li> </ul> </aside>
如上述代码所示,视图文件由Razor标记和标准HTML组成。在此处可以输入任何想要的内容来修改视图的显示效果。
提示
视图非常类似于ASP.NET Web Forms的页面。视图包括HTML内容和脚本。可以使用熟悉的C#语言编写脚本,使用脚本显示动态内容。
3.模型
前面已经讨论控制器和视图,最后讨论一下模型。MVC模型包含所有视图或控制器不包含的应用程序逻辑。模型应该包含所有应用程序业务逻辑和数据库访问逻辑。例如,如果正在使用LINQ to SQL访问数据库,那么将在Models文件夹中创建LINQ to SQL类(dbml文件)。
视图应该只包含与生成用户界面相关的逻辑。控制器应该只包含要求返回正确视图或将用户重定向到另一操作所需的最小逻辑。其他所有内容都应包含在模型中。
总之,应该努力实现高效模型和简化控制器。控制器方法应该只包含几行代码。如果控制器操作过长,则应该考虑将逻辑移动到Models文件夹中的一个新类中。
15.3.4 MVC 4路由规则
除了使用前面列出的文件夹之外,ASP.NET MVC Web应用程序还使用Global.asax文件中的代码来设置全局URL路由默认值。
路由在Global.asax文件的Application_Start()方法中初始化。下面的示例演示一个普通Global.asax文件。
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); //注册路由 BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); } }
Application_Start()方法在应用程序启动时被调用,在方法内对应用程序所需的各种配置信息进行注册。其中路由规则保存在App_Start目录下的RoteConfig.cs文件中,由RouteConfig.RegisterRoutes(RouteTable.Routes)语句来初始化。
RoteConfig类中包含默认路由规则的代码如下。
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); ❶ routes.MapRoute( ❷ name: "Default", //路由名称 url: "{controller}/{action}/{id}", //带有参数的URL defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } //参数默认值 ); } }
在上述代码中定义了两个URL路由。在❶处定义了可以忽略的路由配置,也就是说,不需要路由处理程序去处理这些路由;而在❷处则设置了一个默认的路由。
当ASP.NET MVC应用程序第一次启动时,调用Application_Start()方法。该方法又调用RegisterRoutes()和RegisterRoutes()方法创建默认的路由表。
默认的路由表中包含一个路由。该默认路由将所有进入的请求拆分为三个单元(URL单元是正斜杠之间的所有内容)。第一个单元映射到控制器名称,第二个单元映射到操作名称,最后一个单元映射到传递给操作名称ID的参数。
例如,考虑下面的URL:
/Product/Details/3
此URL被解析为如下三个部分。
Controller = ProductController Action = Details Id = 3
注意
前缀控制器将被附加到控制器参数的末端,这只是MVC的一个特殊之处。
默认路由包括所有三个单元的默认值。默认控制器是HomeController,默认操作是Index,而默认ID是一个空字符串。观察这些默认值,考虑如何解析下面的URL。
/Employee
此URL被解析为如下三个参数。
Controller = EmployeeController Action = Index Id = ""
最后,如果打开ASP.NET MVC应用程序而不提供任何URL(例如http://localhost/),那么URL将被解析为:
Controller = HomeController Action = Index Id = ""
请求将被发送到HomeController类上的Index()操作。
共有条评论 网友评论