asp.net|ASP.NET MVC Controller和Action

这篇文章我将和大家一起来讨论ASP.NET MVC框架中的Controller和Action。本篇文章包含以下内容:
1. 了解Controller
2. Controller接收请求参数
3. 返回ActionResult
了解Controller 当用户请求一个URL地址时,路由系统会将该请求交给一个Controller来进行相应。一般情况下,Controller需要做的是:接收到相关参数,调用下层的Model来处理特定业务逻辑,然后返回一个ActionResult。
在MVC模式中,Controller处于一个中心地位,连接着Model和View。在理想情况下,Web应用程序应该做到“胖模型,瘦控制器,哑视图”。胖模型是指,所有的业务逻辑都存在于Model中,功能强大并且具有比较高的内聚性,瘦控制器是指,控制器的代码应该尽量的精简,不包含任何业务逻辑,也不包含任何界面逻辑,而仅仅包含对参数的提取和对Model以及View的调用。哑视图是指,View对所有的业务逻辑一无所知,仅仅是呈现一个页面,需要的所有数据都由Controller传递过来,不直接调用Model层来获取数据,更不直接访问数据库。
Controller的两个最重要的工作就是:1.处理Web请求,并且接收所有传递的参数。2.相应Web请求,返回特定的ActionResult。
Controller接收请求参数 在Controller的Action中如果想获取本次请求的参数,最直接的方式是可以通过Context的对象来获取,也可以通过Action方法的参数来直接接收(Action方法的参数是通过ModelBinder来赋值的,无需程序员编写任何代码)
从上下文对象中获取参数
通常情况下,我们的controller类都是继承自 System.Web.Mvc.Controller 类,这个父类中有好几个对象,我们可以在自己的控制器中直接使用,如,Request , Response , RouteData , HttpContext , Server, Session 等。下面列举一些常用的情况

属性 类型 描述
Request.QueryString NameValueCollection 从本次Get请求中获取查询字符串的变量和值
Request.Form NameValueCollection 从本次Post请求中获取变量和值
Request.Cookie HttpCookieCollection 本次请求中,浏览器发送的Cookie值
Request.Uri Uri 请求的URL路径
RouteData.Values RouteValueDictionary 路由参数
HttpContext.Session HttpSessionStateBase 获取session中的键值
User IPrincipal 获取当前用户的授权信息
我们在 action 中会这样用
public ActionResult Index() { string info = Request.QueryString["info"] ; ViewBag.Info = info ; return View(); }

从Action方法的参数中获取
当处理请求时,MVC框架会自动从Request.QueryString ,Request.Form ,Request.RouteData.Values 等集合中根据参数名为参数赋值,这些参数不能包含 out 和 ref 关键字 ,大小写不敏感 。
public ActionResult Index( string info ) { ViewBag.Info = info ; return View(); }

绑定参数大概经过这么一个过程,首先,由 data provider 去从上述的几个几何对象中取出值 ,然后赋给data binder ,由 data binder 进行验证、类型转换等操作,然后把值赋给 action 的参数 这个参数的类型可以是任意的 .net 类型 ,具体的绑定方式会在以后的文章中具体说。如果 model binder 无法为某个引用类型的参数找到对应的值,那么会给这个参数赋值为null,如果是值类型的话,就会抛出异常。为了避免这种情况的发生,我们可以手动地为 action 的参数赋默认值,或者给参数定义为可为空的类型,如下面代码所示:
public ActionResult Index(string info ="Hello , World !",int number=0 , double? doubleData) { ViewBag.Info = info ; return View(); }

以上这个过程称为Model Binding,MVC框架不仅可以为为简单的参数赋值,还可能为复杂的对象赋值,也可以给数组和集合赋值,想了解更多请参见 ASP.NET MVC Model Binding
返回ActionResult 当Controller处理完请求之后,需要返回一个结果,比如,返回一个HTML页面、一个文件、一个HTTP Code等。我们可以让 Action 方法返回一坨 HTML标签,但是,这样子写的话不仅效率低,而且不容易维护,也不利于单元测试。我们可以简单地返回一个 ActionResult 对象。MVC框架包含了一系列内置的返回类型,全都继承自ActionResult类,如下所示:
类名 描述 方法名
ViewResult 显示指定的或默认的View模板 View
PartialViewResult 显示指定的或默认的部分页模板 PartialView
RedirectToRouteResult 重定向 RedirectToAction , RedirectToActionPermanent ,RedirectToRoute , RedirectToRoutePermanent
RedirectRestult 重定向 Redirect ,RedirectPermanent
ContentResult 返回纯文本信息 Content
FileResult 返回二进制文件到浏览器 File
JsonResult 将一个.net 对象序列化为Json字符串返回 Json
HttpUnauthorizedResult 返回HTTP 401
HttpNotFountResult 找不到指定文件 404 HttpNotFound
返回ViewResult时,向页面传递数据
有三种方式可以将数据传递到页面上
向视图传递一个 Model 对象 接收数据的视图应该是一个强类型的视图。
public ActionResult About() { DateTime date = DateTime.Now; return View( date ); }

视图页面中的调用方式如下:
@model DateTime @Model.Month

通过ViewBag向视图传递数据。 由于ViewBag是 dynamic 类型的,所以,我们可以给 ViewBag 赋任何属性的值。dynamic类是.net 4.0中的新特性,如果一个对象被声明为了dynamic类型,那么,与该对象有关的任何代码都不参与编译,如果有错误时,会在运行时抛出异常。
public ActionResult About() { ViewBag.Date = DateTime.Now; ViewBag.Message=“hello , world!”; return View(); }

视图页面中的调用方式如下:
@ViewBag.Date @ViewBag.Message

通过 ViewData 向视图传递数据。
public ActionResult About() { ViewData["Date"] = DateTime.Now; ViewData["Message"]=“hello , world!”; return View(); }

视图页面的调用方式(需要强制类型转换)
@ViewData["Date"] @ViewData["Message"]

返回 RedirectResult 对象。
RedirectResult 分为两种,第一种是通常意义上的跳转,第二种是永久跳转,既,在浏览器中通过“后退“是退不回来的,这种跳转的方法名上都是以 “Permanent” 结尾的,例如,RedirectToActionPermanent , RedirectToRoutePermanent 等。各种方法只需要根据重载的参数即可使用,此处就不做介绍了。
返回 ContentResult 对象
如果想返回文本信息,如 XML , HTML ,或者纯文本信息,可以返回ContentResult对象。
return Content("This is content", "text/plain", System.Text.Encoding.Default);

返回 JsonResult 对象
【asp.net|ASP.NET MVC Controller和Action】Json是一种目前比较流行的跨平台的纯文本格式,一般用于Ajax技术。
return Json(JsonData) ;

返回 FileResult 对象
return File("fileName" , "contentType" ,"downloadName") ;

返回错误信息或返回HTTP代码
return new HttpStatusCodeResult(404, " URL not found 。。。") ; return HttpNotFound() ;

    推荐阅读