ASP.NET MVC 控制器
一、控制器概述
Controller(控制器)在ASP.NET MVC中负责控制所有客户端与服务端的交互,并且负责协调Model与View之间数据传递,是ASP.NET MVC框架核心。Controller为ASP.NET MVC框架的核心组成部分,其主要负责处理浏览器请求,并决定响应什么内容给浏览器,但并不负责决定内容应如何显示(View的职责)。
二、 Controller类别和方法
Controller本身就是一个类(Class),该类别有许多方法(Method),这些方法中只要是公开方法(public method)就会被视为是一个动作(Action)或动作方法(Action Method),只要动作存在,就可以通过该动作方法接收客户端传来的要求与决定响应的检视(View)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCControllerDemo.Controllers
{
public class ControllerDemoController : Controller
{
//
// GET: /ControllerDemo/
[HttpGet]
public ActionResult Index()
{
return View();
}
}
}
从如上代码可以总结出Controller应具备如下几个基本条件:
-
Controller必须为公开类别;
-
Controller名称必须以Controller结尾;
-
必须继承自ASP.NET MVC内建的Controller类别,或实现IController自定义类别;
-
所以动作方法必须为公开方法,任何非公开的方法如声明为private或protected的方法都不会被视为一个动作方法;
三、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在运行时还有一层所谓的动作过滤器机制,分为如下四种基本类型:
-
授权过滤器(Authorization Filters);
-
动作过滤器(Action Filters);
-
结果过滤器(Result Filters);
-
例外过滤器(Exception Fiters);
四、 控制器方法类别
4.1 动作方法选定器
当通过ActionInvoker选定Controller内的公开方法时,ASP.NET MVC还有另一个特性称为"动作方法选定器(Action Method Selector)",该选定器可以套用在动作方法上,以便ActionInvoker"选定"适当的Action。
(1)NonAction属性
若控制器某个方法特性为NonAction,即使该Action方法是“公开方法”,也会告知ActionInvoker不要选定这个Action来运行。主要用途:a.保护Controller中的特定公开方法不要发布到Web上;b.功能尚未开发完成就要进行部署,暂时不想将此方法删除。
[NonAction]
public ActionResult Index()
{
return View();
}
也可将public改为private,达到保护的效果。
private ActionResult Index()
{
return View();
}
(2)HTTP动词限定属性
HttpGet、HttpPost、HttpDelete、HttpPut、HttpHead、HttpOptions、HttpPatch属性(Attributes)都是动作方法选定器的一部分。如下例子讲解HttpGet属性,即代表只有当客户端浏览器发送HTTP GET要求时,ActionInvoker才会选定到这个Action:
[HttpGet]
public ActionResult Index()
{
return View();
}
若将[HttpGet]改为[HttpPost],浏览器将找不到资源。
[HttPost]
public ActionResult Index()
{
return View();
}
注释:如果动作方法上没有嵌套任何限定属性,那么客户端浏览器发送任意HTTP动词都会自动选定到对应的Action。
当需要显示接收窗体信息时,可以创建两个同名的Action,分别用HttpGet和HttpPost属性来限定。
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(FormCollection fc)
{
//UpdateToDB(fc);
return RedirectToAction("Index");
}
4.2 操作过滤器
一个操作方法一旦被选中就会立即执行,并且如果它返回一个结果,返回的结果也会随后执行,ASP.NET MVC 5提供五种方式,分别列于如下:
- 即身份验证
- 授权
- 操作前后处理
- 结果前后处理
- 错误处理。
- 除此之外,还有另外一种过滤器,即重写过滤器,它允许为全局或控制器的默认集合制定例外情况。
操作过滤器可以作为直接运用于操作方法或控制器类的特性来编写,或作为在全局过滤器列表中注册的单独类来编写。如果打算将编写的操作过滤器作为特性来使用,那么它必须继承自FilterAttribute或它的任何子类,如ActionFilterAttribute。不作为特性使用的全局操作过滤器没有对这个基类的要求。无论采用哪个路由,操作过滤器支持的过滤活动都由实现的接口决定。
五、 Controller动作结果
5.1 控制器动作结果类型(ActionResult)
通常,在定义一个方法时,我们常规性地根据方法是否有返回值归结为有返回值和无返回值两大类,控制器的本质是类,控制器的action本质是方法,如果按照数学集合来定义,那么控制器是类的一个子集,同理,控制器action是方法的一个子集,因此,在研究控制器以及控制器action时,我们是可以才用研究类和方法的一般思维的。
控制器动作(具体的action)返回的结果叫做控制器动作结果,动作结果是控制器返回给浏览器请求的内容。ASP.NET MVC框架支持六种标准类型的动作结果。
(1)继承ActionResult的动作结果
(2)继承关系
(3)例子
eg1:ViewResult
//方法1: ViewResult作为返回类型
public ViewResult Index()
{
return View();
}
//方法二: ViewResultBase作为返回类型
public ViewResultBase Index()
{
return View();
}
//方法三: ActionResult作为返回类型
public ActionResult Index()
{
return View();
}
eg2:EmptyResult
//GET: /ControllerDemo/
public EmptyResult Index()
{
return null;
}
eg3:ContentResult
//方法1:ContentResult作为返回类型
public ContentResult Index()
{
return Content("Hello World");
}
//方法2:ActionResult作为返回类型
public ActionResult Index()
{
return Content("Hello World");
}
eg4:JsonResult
public JsonResult jsonResult()
2 {
3 TechInfoCompanay jsonCompany=new TechInfoCompanay(){id="S001",CompanyName="信息科技有限公司"};
5 return Json(jsonCompany,JsonRequestBehavior.AllowGet);
6 }
7
8
9 //定义一个公司类
10 public class TechInfoCompanay
11 {
12 public string id { set; get; }
13 public string CompanyName { set; get; }
14 }
eg5:RedirectResult
//方法1:RedirectResult作返回类型
public RedirectResult redirectResult()
{
return Redirect("https://www.google.com.hk/");//具体的URL
}
//方法1: ActionResult作返回类型
public ActionResult redirectResult()
{
return Redirect("https://www.google.com.hk/");//具体的URL
}
eg6:RedirectToRouteResult
public ActionResult redirectResult()
{
return Redirect("https://www.google.com.hk/");//具体的URL
}
public RedirectToRouteResult redirectToRouteResult()
{
return RedirectToAction("Index");
}
5.2 一般方法
(1)如下只是给出方法样式,不做具体代码。
/无返回类型
public void functionName(形参)
{
//to add your content
}
//有返回类型
public 返回类型 functionName(形参)
{
//to add your content
return 与方法返回类型相匹配的结果;
}
(2)例子
eg:举个自定义返回string的方法
RouteConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MVCControllerDemo
{
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 = "ControllerDemo", action = "Index", id = UrlParameter.Optional }
);
}
}
}
ControllerDemoController.action
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCControllerDemo.Controllers
{
public class ControllerDemoController : Controller
{
public string GeneralFunction()
{
return "自定义一般方法";
}
}
}