ASP.NET MVC系列文章

【01】浅谈Google Chrome浏览器(理论篇)

【02】浅谈Google Chrome浏览器(操作篇)(上)

【03】浅谈Google Chrome浏览器(操作篇)(下)

【04】浅谈ASP.NET框架

【05】浅谈ASP.NET MVC运行过程

【06】浅谈ASP.NET MVC 控制器

【07】浅谈ASP.NET MVC 路由

【08】浅谈ASP.NET MVC 视图

【09】浅谈ASP.NET MVC 视图与控制器传递数据

【10】浅谈jqGrid 在ASP.NET MVC中增删改查

【11】浅谈ASP.NET 页面之间传值的几种方式

【12】浅谈缓存技术在ASP.NET中的运用

【13】浅谈NuGet在VS中的运用

【14】浅谈ASP.NET 程序发布过程

【15】浅谈数据注解和验证

【16】浅谈依赖注入

【17】浅谈表单和HTML辅助方法

【18】浅谈基于APS.NET身份验证

【19】浅谈ASP.NET MVC 模型

【20】浅谈ASP.NET MVC 单元测试

【21】浅谈ASP.NET MVC网络安全;

【22】浅谈ASP.NET MVC八大类扩展

【23】再谈ASP.NET MVC Routing

【24】浅谈ASP.NET 高级话题

【25】浅谈大型ASP.NET MVC项目(含DEMO)

【26】下一系列:ASP.NET WebAPI


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)

 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应具备如下几个基本条件:

(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.功能尚未开发完成就要进行部署,暂时不想将此方法删除。

 [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](显示窗体HTML)和[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。不作为特性使用的全局操作过滤器没有对这个基类的要求。无论采用哪个路由,操作过滤器支持的过滤活动都由实现的接口决定。

5  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()
{
TechInfoCompanay jsonCompany=new TechInfoCompanay(){id="S001",CompanyName="信息科技有限公司"};
return Json(jsonCompany,JsonRequestBehavior.AllowGet);
} //定义一个公司类
public class TechInfoCompanay
{
public string id { set; get; }
public string CompanyName { set; get; }
}

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 "自定义一般方法";
}
}
}

测试结果

6  ViewBag、ViewData和TempData概述

6.1 三者在MVC框架里的定义

在MVC框架中,System.Web.Mvc命名空间下的ControllerBase中,对ViewBag、ViewData和TempData三个属性的定义如下

ViewBag

  [Dynamic]
public object ViewBag
{
[return: Dynamic]
get
{
Func<ViewDataDictionary> viewDataThunk = null;
if (this._dynamicViewDataDictionary == null)
{
if (viewDataThunk == null)
{
viewDataThunk = () => this.ViewData;
}
this._dynamicViewDataDictionary = new DynamicViewDataDictionary(viewDataThunk);
}
return this._dynamicViewDataDictionary;
}
}

ViewData

 public ViewDataDictionary ViewData
{
get
{
if (this._viewDataDictionary == null)
{
this._viewDataDictionary = new ViewDataDictionary();
}
return this._viewDataDictionary;
}
set
{
this._viewDataDictionary = value;
}
}

TempData

 public TempDataDictionary TempData
{
get
{
if ((this.ControllerContext != null) && this.ControllerContext.IsChildAction)
{
return this.ControllerContext.ParentActionViewContext.TempData;
}
if (this._tempDataDictionary == null)
{
this._tempDataDictionary = new TempDataDictionary();
}
return this._tempDataDictionary;
}
set
{
this._tempDataDictionary = value;
}
}

6.2 三者比较

(1)ViewData和TempData属性均返回一个具有字典结构的数据容器,即字典类型的key/Value对,ViewBag为Dynamic类型。

三者方法签名为:

  public TempDataDictionary TempData { get; set; }
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定义如下:

 // 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
namespace System.Web.Mvc
{
using System; public abstract class ActionResult
{
protected ActionResult()
{
} public abstract void ExecuteResult(ControllerContext context);
}
}

ActionResult是Action运行后的回传型别,但是当Action回传ActionResult的时候,其实并不包含这个ActionResult(例如ViewResult)的运行结果,而是包含运行这个ActionResult时所需的数据,当MvcHandler从Controller取得ActionResult之后才会去运行出ActionResult的结果。在ActionResult抽象类中仅仅定义了一个ExecuteResult()方法。

ASP.NET 定义了以下几种衍生型别。

8  控制器定义

一般地,在定义Controller时,采用两种方式,即实现IController和继承Controller。

8.1 实现IController

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 }
);
}
}
}

RouteDemoController

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; using System.Reflection;
namespace MVCControllerDemo.Controllers
{
public class ControllerDemoController : IController
{
public String Index()
{
return "<h1>Index</h1>";
} public void Execute(System.Web.Routing.RequestContext requestContext)
{
string action = requestContext.RouteData.Values["action"].ToString();
Type typ = typeof(ControllerDemoController);
MethodInfo md = typ.GetMethod(action, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (md == null)
{
requestContext.HttpContext.Response.Write("<h1>404</h1>");
}
else
{
string s = md.Invoke(this, null).ToString();
requestContext.HttpContext.Response.Write(s);
}
}
}
}

8.2 继承Controller

这种方法比较常用。

 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();
}
}
}

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  版权

  • 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。
  • 博主网址:http://www.cnblogs.com/wangjiming/。
  • 极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。
  • 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2016177728@qq.com。
  • 可以转载该博客,但必须著名博客来源。

详解ASP.NET MVC 控制器的更多相关文章

  1. 详解ASP.NET MVC的请求生命周期

    本文的目的旨在详细描述asp.net mvc请求从开始到结束的每一个过程. 我希望能理解在浏览器输入url并敲击回车来请求一个asp.net mvc网站的页面之后发生的任何事情. 为什么需要关心这些? ...

  2. 详解ASP.NET MVC应用程序请求生命周期

    ------转载当一个ASP.NET MVC应用程序提出请求,为了响应请求,包含一些请求执行流程步骤! 在ASP.NET MVC应用程序Http request 和Http response 过程中, ...

  3. jquery.uploadify上传文件配置详解(asp.net mvc)

    页面源码: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" c ...

  4. 详解Asp.net MVC DropDownLists

    Asp.net MVC中的DropDownLists貌似会让一开始从Asp.net Forms转过来的程序员造成不少迷惑.这篇文章讲述了为了使用DropDownLists,你需要在Asp.Net MV ...

  5. 详解ASP.NET MVC Model验证

    ASP.NET mvc的最好的优点之一就是支持Model验证,这个特性很方便你可以选择在定义Model的时候在字段中采用特性进行注解约定,也可以在代码中自己进行手动验证.下面就来细说一下ASP.NET ...

  6. 【ASP.NET MVC系列】浅谈ASP.NET MVC 控制器

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  7. 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入

    系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...

  8. 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射

    使用Code First建模自引用关系笔记   原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...

  9. ASP.NET MVC 控制器激活(一)

    ASP.NET MVC 控制器激活(一) 前言 在路由的篇章中讲解了路由的作用,讲着讲着就到了控制器部分了,从本篇开始来讲解MVC中的控制器,控制器是怎么来的?MVC框架对它做了什么?以及前面有的篇幅 ...

随机推荐

  1. UART通信

    UART0串口调试过程:1.配置DTS节点 在Z:\rk3399\kernel\arch\arm64\boot\dts\rockchip路径下打开rk3399.dtsi文件,里面已经有UART0相关节 ...

  2. HTML5本地存储之Web Storage应用介绍

    Web Storage是HTML5引入的一个非常重要的功能,可以在客户端本地存储数据,类似HTML4的cookie,但可实现功能要比cookie强大的多,cookie大小被限制在4KB,Web Sto ...

  3. arm处理器

    arm处理器 arm处理器相关 1.体系架构定义了指令集(ISA)和基于这一体系结构下处理器的编程模型. arm卖的是架构或者已经设计好的公版ip核 卖给苹果高通的是架构,需要苹果高通通过架构设计自己 ...

  4. 利用shell脚本监控目录内文件改动

    #! /bin/bash webroot="/home/www/" cp /dev/null rsync_file if [ ! -f   file.md5 ];then      ...

  5. iOS学习之应用之间的操作(转发)

    首先要说的是每一个APP都可以设置一个自己独有的URL,APP应用之间的操作就是通过这个URL来实现的! 1.如何配置自己应用的URL? 关于自己的URL,作为资深的程序猿都会想到 Info.plis ...

  6. Lambda应用场景和使用实例

    Java 8已经推出一段时间了,Lambda是其中最火的主题,不仅仅是因为语法的改变,更重要的是带来了函数式编程的思想.这篇文章主要聊聊Lambda的应用场景及其相关使用示例. Java为何需要Lam ...

  7. jQuery-强大的jQuery选择器、过滤器

    1. 基础选择器 Basics 名称 说明 举例 #id 根据元素Id选择 $("divId") 选择ID为divId的元素 element 根据元素的名称选择, $(" ...

  8. 关于jQuery表单选择中prop和attr的区别。

    今天用jQuery学习表单这一章节的内容,再次遇到表单全选时,不能进行第二次全选的情况.反复查看测试仍然找不到是什么原因.后来在网上查到原来是jQuery1.6以后的版本用到的是prop.用attr的 ...

  9. ES6核心内容精讲--快速实践ES6(三)

    Promise 是什么 Promise是异步编程的一种解决方案.Promise对象表示了异步操作的最终状态(完成或失败)和返回的结果. 其实我们在jQuery的ajax中已经见识了部分Promise的 ...

  10. awk之随机函数rand()和srand() (转)

    转自:http://blog.chinaunix.net/uid-10540984-id-2942041.html 文件: 1234567 abcdefg ......   现在想要随机抽取5列组成下 ...