Controllers入门(Introducing the Controller)
每一个针对应用程序的请求都是通过Controller处理的,controller自由地选择合适的方式来处理这些请求,只要它不偏离到View和Model所负责的区域。这样意味着我们不要把业务或数据存储的逻辑放到Controllers里面,也不要创建用户接口。
在ASP.NET MVC框架里面,Controllers是包含必要的处理请求的.NET类。前面有解释Controller的角色是封装我们的应用程序逻辑。这意味着Controller是负责处理请求,实行对Model的操作,选择View呈现给用户。本次的笔记会介绍Controllers是怎样被实现的以及我们能够接收和创建输出的不同方式。
MVC框架本身并没有限定我们通过View创建HTML,并且会讨论其他可用的选择。同时也会展示Actions方法是如何让单元测试变得简单,以及阐释怎样测试每一种由Actions产生的Results。
下面通过新建一个Project来说明,创建一个ControllersAndActions的项目,选择Empty Template.
1.创建一个实现IController的Controller
在MVC框架里面,Controller类必须实现IController接口:如下
public interface IController { void Execute(RequestContext requestContext); }
这是一个非常简单的接口,只有一个Execute方法,当一个请求在Controller类里面被命中时调用。MVC框架通过读取由routing data创建的Controller属性的值来知道哪一个Controller类被命中。我们能够通过实现IController接口来创建一个Controller类,但是这是非常低级的接口,并且我们要做很多的工作来让Controller变成可用的。
下面的BasicController提供了一个展示。
在上面的Execute方法里面,我们从关联请求的RouteData对象里面读取了controller和action变量的值并写入了输出的结果里面。这时如果我们运行程序并输入:
/Basic/Index,会显示如下:
通过实现IController接口能够让我们创建一个类,这个类是被MVC框架识别为Controller并发送请求给它的。但是要写一个负责的应用程序,这就变得非常艰难。MVC框架不具体到一个controller是如何处理请求的,这也意味着我们能够创建任何方法。
2.创建一个继承Controller类的Controller
MVC框架是无限制地可定制和看扩展的,我们能够实现IController接口创建任何一种我们需要的请求处理和结果生成的Controller类.如果我们不想操作方法,不想关注呈现的视图,那么我们可以把一切事情掌握在自己手里并写出一个更好的,更快的,更加优雅的处理请求的方式,或者我们也可以将controller从System.Web.Mvc.Controller派生,这样就可以使用MVC框架提供的功能。
System.Web.Mvc.Controller类提供了三个关键的功能:
①Action Methods:一个controller类的行为会划分到多个方法里面,每一个方法暴露给不同的URL并使用从请求中提取的参数来调用,这些方法称为Action Methods。
②Action Results:Action Methods的返回值
③Filters:封装一些可重用的行为,使用时只需要在controller和action方法上面添加[Attributes]。
接下来,创建一个DerivedController类并继承Controller,如下:
接收输入(Receiving Input)
Controller需要频繁的访问传入进来的数据,比如querystring,通过路由系统解析参数的值等等。有三种主要的方式来访问这样的数据:
①从context对象提取 ②作为参数传递给action方法的 ③明确的调用框架的模型绑定功能
ps:参数名是忽略大小写的,如Request.Form["City"]跟Request.Form["city"]是一样的。
这里我们主要用前面两种方式,模型绑定会在后面的章节介绍。
1.从Context对象获取数据
当我们创建一个从Controller基类派生的controller时,我们就能够访问一套非常便捷的属性,这些属性包括:Request, Response , RouteData, HttpContext, Server
每一个属性提供请求的一个方面的信息,这些属性都是在ControllerContext实例里面的。在action方法里面是可以使用任何context对象来访问这些属性的,例如:
2.使用Action方法的参数
这种方式比上一种方式要优雅,它让我们的Action方法更易读,下面是一个对比:
其实不仅仅是易读而且有利于单元测试,有一点需要我们注意,action方法里面不允许有ref或out型的参数,这个编译时不会报错,但是运行会抛异常。如下面的实例:
public ActionResult Index(out int a)
{
ViewBag.Message = "Hello from DerivedController Index Method";
a = 1;
ViewBag.Num = a;
return View("Index");
}
Index视图里面的代码如下:
运行抛如下异常:
理解参数对象是怎样被实例化的
Controller基类使用MVC框架的Value Providers(值提供程序)和Model Binders(模型绑定)两个组件来获取action方法参数的值
Value Providers将可用的数据项集合呈现给controller,有内置的value providers从Request.Form, Request.QueryString, Request.Files,RouteData.Values获取数据项。然后这些值会被传递给模型绑定(Model Binders)——将这些值映射到action方法需要的参数的类型。默认的model binders能够创建和填充任何.NET类型的对象,并包含自定义的类型和集合。
理解可选和必须的参数
如果MVC框架不能找到一个引用类型参数的值,action方法仍然会被调用,但是使用的null值。如果是一个值类型的值没有找到,那么会发生异常并且action方法不会被调用。
①值类型的从参数是必须的被赋值的。如果想让这个跟引用类型一样,可以这样定义int?,当依然没有找到值时,不会发生异常,而是会传递null值。
②引用类型的参数是可选的。为了让它变成必选的(保证一个非空的值被传递),在action方法的上面添加一些代码拒绝null值
指定默认参数的值
如果我们要处理不包含action方法参数值的请求,但是又不想去检查null值。这时可以使用C#可选参数的特性,如下:
public ActionResult Search(string query="all",int page=1){...}
今天的笔记就到这里,后面一篇笔记还是关于这部分的内容。笔记里面不对的地方还请路过的朋友指正,谢谢!
晚安!
本文转自Rt-张雪飞博客园博客,原文链接http://www.cnblogs.com/mszhangxuefei/archive/2012/03/06/mvcnotes_22.html如需转载请自行联系原作者
张雪飞