MVC4学习笔记

MVC4学习笔记1.URL Routing——URL路由1.1. 路由系统是神奇的,它由一组路由规则构成。对于一个应用程序来说,这些路由规则完全地匹配那些你的应用程序需要识别并且响应的URL请求。1.2.URL地址可以被分割成一组字符串片段。比如:http://aa.com/bb/cc/…,其中bb即为该URL地址的第一部分片段,cc即为该URL地址的第二部分片段,依此类推。1.3.路由系统通过“{controller}/{action}”(即“{控制器}/{行为}”)来识别URL地址的第一部分片段和第二部分片段间的关系。比如1.2中的地址的意思是调用名称为bb的控制器的名称为cc的行为来对该URL请求进行响应。1.4.路由系统就是通过上面的这种模式,将URL地址中的各个字符串片段提取出来,然后映射到相应的{controller}及{action}参数上,然后调用相应的{controller}下的{action}。1.5.这种URL地址的匹配模式是一种保守的匹配模式,也就是说,它将只匹配那些拥有相同片段数的URL地址。假定有一种模式{controller}/{action},那么它只能匹配拥有两个URL片段的URL地址,如http://aa.com/bb/cc或http://aa.com/xx/yy,而不能匹配http://aa.com/bb或http://aa.com/bb/cc这样的地址,因为前面两个都是由两组URL片段组成,而后面两个的URL片段都不是两组,所以不能匹配,这就叫做保守匹配。1.6.RouteConfig.cs文件存储着程序的路由规则,它会在应用程序开始的时候由Global.asax.cs调用。1.7.创建一个路由规则,比如: routes.MapRoute( name: “myRoute”, //名为myRoute的路由规则 url: “{controller}/{action}” //匹配只拥有两段URL片段的URL );1.8.创建一个带默认值的路由规则,比如: routes.MapRoute( name: “myRoute”, //名为myRoute的路由规则 url: “{controller}/{action}”, //匹配只拥有两段URL片段的URL defaults: new { action = “index” } //设定{action}的默认值为index );所谓默认值,即是当该URL片段缺省时,将使用默认值。比如当请求的URL为http://aa.com/bb时,路由系统将调用bb控制器下的index行为,而当URL为http://aa.com/bb/cc时,路由系统将调用bb控制器下的cc行为,这就是默认值的作用。1.9.创建一个带静态URL片段的路由规则,比如: routes.MapRoute( name: “myRoute”, //名为myRoute的路由规则 url: “admin/{controller}/{action}”, //其中的“admin”即为静态路由片段 defaults: new { controller = “default”, action = “index” } //设定默认值 );或者 routes.MapRoute( name: “myRoute”, //名为myRoute的路由规则 url: “{controller}/{action}.html”, //其中的“.html”即为静态路由片段 defaults: new { controller = “default”} //设定默认值 );1.10.路由规则的匹配是按照路由规则在RouteCollection中的顺序进行的,也就是说,路由规则在RouteCollection中注册得越早,URL地址就将优先匹配该规则。路由系统会试图将请求的URL地址的模式去匹配最先注册的路由规则,除非规则不匹配才会跳到下一个注册的路由规则来进行匹配。比如: routes.MapRoute( name: “myRoute1”, url: “/{controller}/{action}”, defaults: new { action = “index” } ); routes.MapRoute( name: “myRoute2”, url: “/{controller}/{action}”, defaults: new { action = “main” } );当有URL请求http://aa.com//bb发生时,路由系统是选择bb控制器下的index行为,还是main行为呢,因为它们都能处理请求的URL地址。这时,路由规则的注册顺序就就决定了哪个路由规则会被使用,myRoute1先行进行了注册,所以路由系统会选择myRoute1作为http://aa.com//bb请求的处理规则。1.11.创建混合的路由规则示例 routes.MapRoute( name: “myRoute”, url: “admin/{controller}/{action}”, defaults: new { action = “index” } );这里既有admin(静态路由规则)又有action=index这样的默认路由规则,所有可以多种路由规则共用。1.12.创建不限制URL长度的路由规则,如: routes.MapRoute( name: “myRoute”, url: “{controller}/{action}/{id}/{*other}”, defaults: new { action = “index”, other = UrlParameter.Optional } );“*”表示从该处开始向后的所有URL字符串,“other”是URL片段名。如:http://aa.com/bb/cc/123/xx/yy/zz,那么string other = RouteData.Values[“other”].ToString();的值为xx/yy/zz。1.13.创建使用正则表达式的路由规则,例: routes.MapRoute( name: “myRoute”, url: “{controller}/{action}/{id}”, defaults: new { action = “index” }, constraints: new { id = “^1|2|3$” } );我们可以在constraints参数中定义各个URL片段的正则表达式匹配规则,上面的规则定义了id为1、2、3其中的一个,如果id不为其中的值则不匹配该规则。1.14.通过RouteData.Values获取URL地址的属性值(片段值),例:请求的URL地址为http://aa.com/bb/cc/123,那么string id = RouteData.Values[“id”].ToString();获得的值为123。1.15.创建自定义的路由基类1.15.1.自定义路由基类继承自RouteBase类,它能让您知道URL地址是如何匹配的、URL片段是如何提取的、动态的URL输出链接是如何生成的。1.15.2.自定义路由必须重写public override RouteData GetRouteData(HttpContextBase httpContext)方法,该方法揭示了请求的URL匹配的原理,即路由是如何匹配的。1.15.3.自定义路由也必须重写public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)方法,该方法揭示了输出的URL的生成原理。1.15.4.示例public class MyRoute : RouteBase { //处理请求 public override RouteData GetRouteData(HttpContextBase httpContext) { RouteData routeData = null; //获取所有的URL片段组 string[] urls = httpContext.Request.Url.Segments; //片段URL片段组的长度 if (urls.Length == 1) { //实例化RouteData对象,实例化时参数不能缺省 routeData = new RouteData(this, new MvcRouteHandler()); //添加URL片段 routeData.Values.Add(“controller”, “default”); routeData.Values.Add(“action”, “index”); routeData.Values.Add(“id”, DateTime.Now.Second); } return routeData; } //输出URL public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { //不进行处理时,直接返回null return null; } }声明好了自定义的路由规则,需要将它注册到RouteCollection中,如下routes.Add(new MyRoute());然后调试一下试试看。2. 在细分工作区中工作2.1.MVC支持工作区的划分,对于一个大的项目而言,工作区的划分能大大增加项目管理的便捷性2.2.工作区是一个单独的文件夹,它是一个MVC项目下的子项目2.3.右击项目->添加->“Area”2.4.工作区的路由规则需要特别注意,由于暂时用不上这里就不说了,要用时再查查3.Controllers and actions(控制器与行为)3.1.所有的URL请求最终将由控制器来进行处理3.2.控制器包含三个重要的要素3.2.1.行为方法(action)3.2.2.行为结果(action result)3.2.3.过滤器(filters)3.2.3.1.AcceptVerbs,规定页面访问形式get/post等3.2.3.2.ActionName,当不想使用方法名作为actionName时,可以使用该过滤器来设定其ActionName3.2.3.3.Nonaction,当不想让controller下的方法为Action时使用,使用后方法仅为方法3.2.3.4.Outputcache,用于缓存一个action的输出,这样,相同的请求对应的相同的响应就可以被重复使用了3.2.3.4.1.Duration,秒,缓存的时间3.2.3.4.2.Location,缓存类型,客户端|服务器端|。。。3.2.3.4.3.例:[OutputCache(Duration=10)],缓存10秒钟3.3.从请求对象中获取输入的参数3.3.1.Form3.3.2.QueryString3.3.3.Cookie3.3.4.Url3.3.5.RouteData.Values3.3.6.Cache3.3.7.Session3.3.8…….3.4.从controller中向view中传递视图对象,例Controller中: public ActionResult Index() { //获取一个datetime对象 DateTime tm = DateTime.Now; //将datetime对象传递给视图index.cshtml //这样tm就为index视图的默认视图对象了 return View(tm); }Index.csthml中:<!–model为视图对象关键字,在此声明其类型–>@model DateTime<!–Model为从controller中获取的视图对象,通过上面的类型声明可直接访问其属性和方法–><div>@Model.Second</div>3.5.从controller中向view中传递任意对象,使用ViewBag,例Controller中: public ActionResult Index() { ViewBag.time = DateTime.Now; ViewBag.msg = “hello”; return View(); }Index.cshtml中:@{ //通过ViewBag获取controller中的time对象 DateTime time = ViewBag.time; //将time的属性值输出 //(注意,当需要执行cs代码时都需要@符号, //判断是否为cs代码看其背景是否为灰色就可知) <div>@time.Date</div> <div>@time.Second</div>}<div>@ViewBag.time</div><div>@ViewBag.msg</div>ViewBag非常有用,是我们最常使用的controller到view间的数据传递媒介。3.6.异常时的重定向处理 <system.web> <customErrors mode=”On” defaultRedirect=”Error”></customErrors> </system.web>当处理请求发生错误时,请求将转向名为Error的controller页面,所以,需要建立一个ErrorController和其想对应的action及view。4.视图(view)4.1.Section,可以控制一个框架(layout)的部分内容,当我们使用了layout页面时,其中的某个或者某几个页面需要单独地控制部分的layout中的代码时可以使用section,示例:Layout的内容如下:<!DOCTYPE html><html><head> <meta charset=”utf-8″ /> <meta name=”viewport” content=”width=device-width” /> <title>@ViewBag.Title</title></head><body> <!–在此处加载名为sectionTest的section–> <!–false表示section是否必须,一般为false,否则就成layout了–> @RenderSection(“sectionTest”, false) <br /> <!–view的内容将在此处加载–> @RenderBody()</body></html>View的内容如下:<!–定义名为sectionTest的section–>@section sectionTest{ <div>这是来自view的section的内容</div>}<div>这是来自view的内容</div>如上,执行后可知,view中的非section内容由renderBody()函数进行了呈现,而“sectionTest”的内容由“RenderSection(“sectionTest”, false)”进行了呈现。其中,false的意思是别的页面没有定义名为sectionTest的section的话,也没关系,layout中这部分就不管了,但是如果是true而页面中又没定义相应的section的话则会报错。4.2.Partial view(局部视图)4.2.1.局部视图是分离的视图文件,它包含了部分的视图代码,并且可以被加载到其它的view中4.2.2.新建名为“myPart”的PartView文件<div> 这是来自part view的代码</div>4.2.3.加载PartView<!–partial有返回值,它会将结果返回到页面中来,然后再拼接输出–>@Html.Partial(“loginPart”)<!–renderPartial没有返回值,它直接向Response输出结果–>@{Html.RenderPartial(“loginPart”);4.3.Child Action(子行为)4.3.1.子行为(child action)与行为(action)的关系就像局部视图(part view)与视图(view)间的关系4.3.2.子行为关键字,[ChildActionOnly],使用了该关键字的为子行为4.3.3.示例在controller中添加以下代码: [ChildActionOnly] public ActionResult Msg() { return PartialView(“Msg”, DateTime.Now); }添加上面的Action对应的View,代码如下:@model DateTime<div>@Model.Second</div>在view中通过Action或RenderAction调用该子行为:<!–Action有返回值,它会将结果返回到页面中来,然后再拼接输出–>@Html.Action(“Msg”)<!–RenderAction没有返回值,它直接向Response输出结果–>@{Html.RenderAction(“Msg”);}通过以上的对比,我们可以发现,当我们只进行html页面的操作时,我们使用Part view;当我们需要在part view中与cs代码进行交互时,我们采用child action。这是这二者最大的区别。5.Helper methods5.1.我们可以使用helper关键字在view中建立函数并调用5.2.示例<!–使用@helper关键字创建函数–>@helper showTimes(int count){ for (int i = 0; i < count; i++) { <div>@i——————-@DateTime.Now</div> }}<!–调用函数–>@showTimes(10)

不给自己一点轻松的机会,好象世界的每个角落都需要自己的脚去留个痕迹,才叫人生。

MVC4学习笔记

相关文章:

你感兴趣的文章:

标签云: