控制器是mvc中的核心,负责处理浏览器传来的所有要求,并决定响应什么属性给浏览器。
控制器本身就是一个类,该类别有许多方法,这些方法中只要是公开方法public,就会被视为一个动作action或动作方法,只要有动作存在,就可以通过动作方法接收客户端传来的要求与决定响应器响应的检视。
基本要求:
控制器必须为公开类别
名称必须以Controller结尾
必须继承自asonet mvc内建的Controller类别,或继承有实作IController界面的自定义类别,或者自行实作IController界面
所有动作方法必须为公开方法,任何非公开的方法如申明private 或者protected的方法都不会被视为一个动作方法。
当控制器被MvcHandler(MH)选中之后,下一步就是通过ActionInvoker(AI)选定适当的Action来运行,在控制器中的每一个Action可以定义0到多个参数,AI会依据当下的RouteValue与客户端传来的数据准备好可传入Action参数的数据,最后正式调用Controller中被选中的那个Action方法。
参数传入的属性都是通过一种称为模型绑定Model Binding机制,从RequestContext取得数据,并将数据对应或传入方法的参数中,让Action不用再像之前asp或aspnet webform中经常使用的Request.Form 或Request.QueryString等对象来取得客户端的数据,通过自定义的模型绑定,甚至可以让你对应出了Request.Form或Request.QueryString以外的数据来源,例如HTTP Cookies,HTTP Headers等
Action运行完后的回传值通常是ActionResult类别或其衍生类别(Derived Classes)事实上,ActionResult是一个抽象类。因此,mvc本身就实作了许多不同类型的Actionresult的子类别,
例如ViewResult用来回传一个View ,
RedirectResult用来将网页转向其他网址,
ContentResult回传一个文字属性,
FileResult回传一个二进制的文档,
这些都是集成自ActionResult的类型。
MH从控制器得到ActionResult之后,就会开始运行ActionResult提供的ExecuteResult方法,并将运行结果响应到客户端,这时控制器的任务就算完成。
不过控制器在运行时还有一层所谓的动作过滤器机制
授权过滤器,动作过滤器
结果过滤器,例外过滤器
所以控制器的运行过程还必须考虑到动作过滤器的运行顺序
当AI找不到对应Action动作时,默认就会运行到System.Web.Mvc.Controller类别的HandleUnknowAction方法,这个方法默认会响应HTTP 404找不到资源的错误信息。
而在控制器的这个基类里面,HandleUnknowAction被标注为virtual虚的,代表这个方法可以被替换override,因此可以在项目的控制器中替换HandleUnknowAction方法,就可以自定义当找不到对应的action时的处理方式,。
eg:
protected override void HandleUnknowAction(string actionname){
Response.Redirect(url);
}
如果在Action前加上ActionName属性并指名为aaa,那么路由参数action的值就会变成必须是aaa才会正确运行到这个对应的动作方法,同时如果去return view()的话,mvc会去寻找aaa.cshtml这个页面,而不是action名称对应的页面,就相当于对这个动作方法名称作了变更。
[ActionName("aa")]
public ActionResult Index(){
return View();
}
NonAction属性
若套用NonAction属性在控制器的动作方法上时,即便该action是public,也会被告知ActionInvoker不要选定这个action来运行,这个属性的用途:为了保护控制器中的特定公开方法不要发布到web上,或是功能尚未开发完整就要进行部署,暂时不想删除就可以套用这个属性不要对外公开。
[NonAction]
public ActionResult Index(){
return View();
}
将Action方法的public更改为private也可以达到这个效果。