ASP.NET MVC系列文章html
【01】浅谈Google Chrome浏览器(理论篇)json
【02】浅谈Google Chrome浏览器(操做篇)(上)浏览器
【03】浅谈Google Chrome浏览器(操做篇)(下)缓存
【04】浅谈ASP.NET框架 安全
【05】浅谈ASP.NET MVC运行过程 网络
【06】浅谈ASP.NET MVC 控制器 mvc
【07】浅谈ASP.NET MVC 路由 框架
【08】浅谈ASP.NET MVC 视图 ide
【09】浅谈ASP.NET MVC 视图与控制器传递数据post
【10】浅谈jqGrid 在ASP.NET MVC中增删改查
【13】浅谈NuGet在VS中的运用
【14】浅谈ASP.NET 程序发布过程
1 概述
在阅读本篇博文时,建议结合上篇博文:详解ASP.NET MVC 路由 一块儿阅读,效果可能会更好些。
Controller(控制器)在ASP.NET MVC中负责控制全部客户端与服务端的交互,而且负责协调Model与View之间数据传递,是ASP.NET MVC框架核心。Controller为ASP.NET MVC框架的核心组成部分,其主要负责处理浏览器请求,并决定响应什么内容给浏览器,但并不负责决定内容应如何显示(View的职责)。
文章内容包括:Controller概述、Controller类别和方法、Controller运行过程、Controller方法类别、ViewData\ViewBag\TempData分析、ActionResult解说、Controller定义和参考文献,剩下有关Controller其余内容在本篇文章中不讲,如Controller激活机制(Controller类型解析、Controller类型缓存、Controller的释放和会话状态行为控制等)、ControllerFactory、ControllerBuilder等,除此以外,文中有些过于涉及到底层的内容,考虑篇幅等因素,只是简要说起了一下,并未作深刻分析,根据后期状况,会酌情考虑是否再写一篇完全深刻的底层Controller的。
2 Controller类别和方法
Controller自己就是一个类(Class),该类别有许多方法(Method),这些方法中只要是公开方法(public method)就会被视为是一个动做(Action)或动做方法(Action Method),只要动做存在,就能够经过该动做方法接收客户端传来的要求与决定响应的检视(View)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6
7 namespace MVCControllerDemo.Controllers 8 { 9 public class ControllerDemoController : Controller 10 { 11 //
12 // GET: /ControllerDemo/
13
14 [HttpGet] 15 public ActionResult Index() 16 { 17 return View(); 18 } 19 } 20 }
从如上代码能够总结出Controller应具有以下几个基本条件:
(1)Controller必须为公开类别;
(2)Controller名称必须以Controller结尾;
(3)必须继承自ASP.NET MVC内建的Controller类别,或实现IController自定义类别;
(4)因此动做方法必须为公开方法,任何非公开的方法如声明为private或protected的方法都不会被视为一个动做方法;
3 Controller的运行过程
当Controller被MvcHandler选中以后,下一步就是经过ActionInvoker选定适当的Action来运行。在Controllr中的每一个Action能够定义0到多个参数,ActionInvoker会依据当下的RouteValue与客户端传来的数据准备好可传入Action参数的数据,最后正式调用Controller中被选中的那个Action方法。参数传入的属性都是经过一种称为模型绑定(Model Binding)机制,从RequestContext取得数据,并将数据对应或传入方法的参数中,让Action不用再像以前ASP或ASP.NET Web Forms中常用的Request.Fomr或Request.QueryString等对象来取得客户端的数据,经过自定义的模型绑定,甚至可让你对应除了Request.Form或Request.QueryString之外的数据来源,例如:HTTP Cookies、HTTP Headers等等。
Action运行完后的回传值一般是ActionResult类别或其衍生类别(Derived Class),事实上,ActionResult是一个抽象类,如ViewResult用来回传一个View、RedirectResult用来将网页重定向、Content回传文字内容、FileResult回传二进制文档等,这些均是继承ActionResult。MvcHandler从Controller获得ActionResult以后,就会开始运行ActionResult提供的ExecuteResult方法,并将运行结果响应到客户端,这时Controller的任务就算完成。
以上为Controller的基本运行过程。Controller在运行时还有一层所谓的动做过滤器机制,分为以下四种基本类型:
(1)受权过滤器(Authorization Filters);
(2)动做过滤器(Action Filters);
(3)结果过滤器(Result Filters);
(4)例外过滤器(Exception Fiters);
4 控制器方法类别
4.1 动做方法选定器
当经过ActionInvoker选定Controller内的公开方法时,ASP.NET MVC还有另外一个特性称为"动做方法选定器(Action Method Selector)",该选定器能够套用在动做方法上,以便ActionInvoker"选定"适当的Action。
(1)NonAction属性
若控制器某个方法特性为NonAction,即便该Action方法是“公开方法”,也会告知ActionInvoker不要选定这个Action来运行。主要用途:a.保护Controller中的特定公开方法不要发布到Web上;b.功能还没有开发完成就要进行部署,暂时不想将此方法删除。
1 [NonAction] 2 public ActionResult Index() 3 { 4 return View(); 5 }
也可将public改成private,达到保护的效果。
1 private ActionResult Index() 2 { 3 return View(); 4 }
(2)HTTP动词限定属性
HttpGet、HttpPost、HttpDelete、HttpPut、HttpHead、HttpOptions、HttpPatch属性(Attributes)都是动做方法选定器的一部分。以下例子讲解HttpGet属性,即表明只有当客户端浏览器发送HTTP GET要求时,ActionInvoker才会选定到这个Action:
1 [HttpGet] 2 public ActionResult Index() 3 { 4 return View(); 5 }
若将[HttpGet]改成[HttpPost],浏览器将找不到资源。
1 [HttPost] 2 public ActionResult Index() 3 { 4 return View(); 5 }
注释:若是动做方法上没有嵌套任何限定属性,那么客户端浏览器发送任意HTTP动词都会自动选定到对应的Action。
当须要显示接收窗体信息时,能够建立两个同名的Action,分别用[HttpGet](显示窗体HTML)和[HttpPost](接收窗体输出的值)属性来限定。
1 [HttpGet] 2 public ActionResult Index() 3 { 4 return View(); 5 } 6
7 [HttpGet] 8 public ActionResult Create() 9 { 10 return View(); 11 } 12
13
14 [HttpPost] 15 public ActionResult Create(FormCollection fc) 16 { 17 //UpdateToDB(fc);
18 return RedirectToAction("Index"); 19 }
4.2 操做过滤器
一个操做方法一旦被选中就会当即执行,而且若是它返回一个结果,返回的结果也会随后执行,ASP.NET MVC 5提供五种方式,分别列于以下:
除此以外,还有另一种过滤器,即重写过滤器,它容许为全局或控制器的默认集合制定例外状况。
操做过滤器能够做为直接运用于操做方法或控制器类的特性来编写,或做为在全局过滤器列表中注册的单独类来编写。若是打算将编写的操做过滤器做为特性来使用,那么它必须继承自FilterAttribute或它的任何子类,如ActionFilterAttribute。不做为特性使用的全局操做过滤器没有对这个基类的要求。不管采用哪一个路由,操做过滤器支持的过滤活动都由实现的接口决定。
5 Controller动做结果
5.1 控制器动做结果类型(ActionResult)
一般,在定义一个方法时,咱们常规性地根据方法是否有返回值归结为有返回值和无返回值两大类,控制器的本质是类,控制器的action本质是方法,若是按照数学集合来定义,那么控制器是类的一个子集,同理,控制器action是方法的一个子集,所以,在研究控制器以及控制器action时,咱们是能够才用研究类和方法的通常思惟的。
控制器动做(具体的action)返回的结果叫作控制器动做结果,动做结果是控制器返回给浏览器请求的内容。ASP.NET MVC框架支持六种标准类型的动做结果。
(1)继承ActionResult的动做结果
(2)继承关系
(3)例子
eg1:ViewResult
1 //方法1: ViewResult做为返回类型
2 public ViewResult Index() 3 { 4 return View(); 5 } 6
7
8
9 //方法二: ViewResultBase做为返回类型
10 public ViewResultBase Index() 11 { 12 return View(); 13 } 14
15 //方法三: ActionResult做为返回类型
16 public ActionResult Index() 17 { 18 return View(); 19 }
eg2:EmptyResult
1 // GET: /ControllerDemo/
2 public EmptyResult Index() 3 { 4 return null; 5 }
eg3:ContentResult
1 //方法1:ContentResult做为返回类型
2 public ContentResult Index() 3 { 4 return Content("Hello World"); 5 } 6
7
8 //方法2:ActionResult做为返回类型
9 public ActionResult Index() 10 { 11 return Content("Hello World"); 12 }
eg4:JsonResult
1 public JsonResult jsonResult() 2 2 { 3 3 TechInfoCompanay jsonCompany=new TechInfoCompanay(){id="S001",CompanyName="信息科技有限公司"}; 4 5 return Json(jsonCompany,JsonRequestBehavior.AllowGet); 5 6 } 6 7
7 8
8 9 //定义一个公司类
9 10 public class TechInfoCompanay 10 11 { 11 12 public string id { set; get; } 12 13 public string CompanyName { set; get; } 13 14 }
eg5:RedirectResult
1 //方法1:RedirectResult做返回类型
2 public RedirectResult redirectResult() 3 { 4 return Redirect("https://www.google.com.hk/");//具体的URL
5 } 6
7 //方法1: ActionResult做返回类型
8 public ActionResult redirectResult() 9 { 10 return Redirect("https://www.google.com.hk/");//具体的URL
11 }
eg6:RedirectToRouteResult
1 public ActionResult redirectResult() 2 { 3 return Redirect("https://www.google.com.hk/");//具体的URL
4 } 5
6 public RedirectToRouteResult redirectToRouteResult() 7 { 8 return RedirectToAction("Index"); 9 }
5.2通常方法
(1)以下只是给出方法样式,不作具体代码。
1 //无返回类型
2 public void functionName(形参) 3 { 4 //to add your content
5 } 6
7 //有返回类型
8 public 返回类型 functionName(形参) 9 { 10 //to add your content
11 return 与方法返回类型相匹配的结果; 12 }
(2)例子
eg:举个自定义返回string的方法
RouteConfig.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.Web.Routing; 7
8 namespace MVCControllerDemo 9 { 10 public class RouteConfig 11 { 12 public static void RegisterRoutes(RouteCollection routes) 13 { 14 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15
16 routes.MapRoute( 17 name: "Default", 18 url: "{controller}/{action}/{id}", 19 defaults: new { Controller = "ControllerDemo", action = "Index", id = UrlParameter.Optional } 20 ); 21 } 22 } 23 }
ControllerDemoController.action
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6
7 namespace MVCControllerDemo.Controllers 8 { 9 public class ControllerDemoController : Controller 10 { 11
12 public string GeneralFunction() 13 { 14 return "自定义通常方法"; 15 } 16 } 17 }
测试结果
6 ViewBag、ViewData和TempData概述
6.1 三者在MVC框架里的定义
在MVC框架中,System.Web.Mvc命名空间下的ControllerBase中,对ViewBag、ViewData和TempData三个属性的定义以下
ViewBag
1 [Dynamic] 2 public object ViewBag 3 { 4 [return: Dynamic] 5 get
6 { 7 Func<ViewDataDictionary> viewDataThunk = null; 8 if (this._dynamicViewDataDictionary == null) 9 { 10 if (viewDataThunk == null) 11 { 12 viewDataThunk = () => this.ViewData; 13 } 14 this._dynamicViewDataDictionary = new DynamicViewDataDictionary(viewDataThunk); 15 } 16 return this._dynamicViewDataDictionary; 17 } 18 }
ViewData
1 public ViewDataDictionary ViewData 2 { 3 get
4 { 5 if (this._viewDataDictionary == null) 6 { 7 this._viewDataDictionary = new ViewDataDictionary(); 8 } 9 return this._viewDataDictionary; 10 } 11 set
12 { 13 this._viewDataDictionary = value; 14 } 15 }
TempData
1 public TempDataDictionary TempData 2 { 3 get
4 { 5 if ((this.ControllerContext != null) && this.ControllerContext.IsChildAction) 6 { 7 return this.ControllerContext.ParentActionViewContext.TempData; 8 } 9 if (this._tempDataDictionary == null) 10 { 11 this._tempDataDictionary = new TempDataDictionary(); 12 } 13 return this._tempDataDictionary; 14 } 15 set
16 { 17 this._tempDataDictionary = value; 18 } 19 }
6.2 三者比较
(1)ViewData和TempData属性均返回一个具备字典结构的数据容器,即字典类型的key/Value对,ViewBag为Dynamic类型。
三者方法签名为:
1 public TempDataDictionary TempData { get; set; } 2 public ViewDataDictionary ViewData { get; set; } 3 public object ViewBag { [return: Dynamic] get; }
(2)TempData存储临时数据,而且设置的变量在被第一次读取后会被移除,即TempData设置的变量只能被读取一次。(why?)
(3)ViewBag和ViewData属性是同一份数据的不一样表现形式,两者的不一样之处在于前者是一个动态对象,能够为其指定任意属性(动态属性名将做为数据字典的Key)。
(4)三者均是容器,即能存储常量,变量,也能存储集合。
7 ActionResult解说
在ASP.NET MVC框架中,对ActionResult定义以下:
1 // Generated by .NET Reflector from C:\Users\WJM\documents\visual studio 2013\Projects\DEMOMVC\packages\Microsoft.AspNet.Mvc.5.0.0\lib\net45\System.Web.Mvc.dll 2 namespace System.Web.Mvc 3 { 4 using System; 5 6 public abstract class ActionResult 7 { 8 protected ActionResult() 9 { 10 } 11 12 public abstract void ExecuteResult(ControllerContext context); 13 } 14 }
ActionResult是Action运行后的回传型别,可是当Action回传ActionResult的时候,其实并不包含这个ActionResult(例如ViewResult)的运行结果,而是包含运行这个ActionResult时所需的数据,当MvcHandler从Controller取得ActionResult以后才会去运行出ActionResult的结果。在ActionResult抽象类中仅仅定义了一个ExecuteResult()方法。
ASP.NET 定义了如下几种衍生型别。
8 控制器定义
通常地,在定义Controller时,采用两种方式,即实现IController和继承Controller。
8.1 实现IController
RouteConfig.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using System.Web.Routing; 7 8 namespace MVCControllerDemo 9 { 10 public class RouteConfig 11 { 12 public static void RegisterRoutes(RouteCollection routes) 13 { 14 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 16 routes.MapRoute( 17 name: "Default", 18 url: "{controller}/{action}/{id}", 19 defaults: new { Controller = "ControllerDemo", action = "Index", id = UrlParameter.Optional } 20 ); 21 } 22 } 23 }
RouteDemoController
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 7 using System.Reflection; 8 namespace MVCControllerDemo.Controllers 9 { 10 public class ControllerDemoController : IController 11 { 12 public String Index() 13 { 14 return "<h1>Index</h1>"; 15 } 16 17 18 19 public void Execute(System.Web.Routing.RequestContext requestContext) 20 { 21 string action = requestContext.RouteData.Values["action"].ToString(); 22 Type typ = typeof(ControllerDemoController); 23 MethodInfo md = typ.GetMethod(action, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 24 if (md == null) 25 { 26 requestContext.HttpContext.Response.Write("<h1>404</h1>"); 27 } 28 else 29 { 30 string s = md.Invoke(this, null).ToString(); 31 requestContext.HttpContext.Response.Write(s); 32 } 33 } 34 } 35 }
8.2 继承Controller
这种方法比较经常使用。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 7 namespace MVCControllerDemo.Controllers 8 { 9 public class ControllerDemoController : Controller 10 { 11 // 12 // GET: /ControllerDemo/ 13 14 [HttpGet] 15 public ActionResult Index() 16 { 17 return View(); 18 } 19 } 20 }
9 参考文献
【01】http://www.cnblogs.com/wangiqngpei557/p/3390812.html
【02】http://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_controller.html
【03】http://www.360doc.com/content/12/0611/15/29831_217456312.shtml
【04】http://blog.csdn.net/yw1688/article/details/51280665
【05】Professional Asp.net MVC 5
【06】Professional Asp.net MVC 4
【07】The framework of revelation of Professional Asp.net MVC 5
【08】 https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/aspnet-mvc-controllers-overview-cs
10 版权