ASP.NET MVC5(.NET Framework)底层完整运行逻辑

一、应用启动(只跑一次,网站第一次访问)

  1. 触发 Global.asax Application_Start
  2. 注册路由:RouteTable.Routes.Add,路由规则全部放进全局静态路由表 RouteTable
  3. 注册Area、Filter、绑定器、视图引擎等 > RouteTable 是全局静态,所有请求共用

二、单次HTTP请求完整链路(重点,每一次请求都走一遍)

scss 复制代码
IIS → ASP.NET管道 → HttpApplication → UrlRoutingModule(IHttpModule)
→ 匹配路由 → MvcRouteHandler → MvcHandler(IHttpHandler)
→ ControllerFactory 创建Controller
→ Controller.Execute()
→ ControllerActionInvoker(Action调用器)【这里就是Filter执行的地方!】
    → 1. IAuthorizationFilter 【自定义CustomAuthentication就在这里】
    → 模型绑定 ModelBinder
    → 2. IActionFilter OnActionExecuting
    → 执行Action方法
    → 3. IActionFilter OnActionExecuted
    → 4. IResultFilter OnResultExecuting
    → ActionResult.ExecuteResult()(渲染View/输出Json)
    → 5. IResultFilter OnResultExecuted
→ 异常Filter IExceptionFilter(只有抛异常才触发)
→ 写回Response

分步拆解

  1. UrlRoutingModule(HttpModule,MVC入口) 模块拦截请求,拿URL去 RouteTable 匹配;匹配成功生成 RouteData(controller、action、area、路由参数),构造 RequestContext;拿到路由对应的 IRouteHandler,默认是 MvcRouteHandler

    没有匹配路由:请求退回普通ASP.NET处理(404)

  2. MvcRouteHandler 只干一件事:创建 MvcHandler(IHttpHandler),交给ASP.NET管道执行。

    Module 是拦截器 ,Handler是最终处理端点

  3. MvcHandler

  • 调用 DefaultControllerFactory(控制器工厂),根据RouteData里的controller名字,反射找Controller类型、实例化Controller

  • 构建 ControllerContext

  • 调用 controller.Execute()

4.Controller 基类 ExecuteCore 内部拿到 ActionInvoker(默认 ControllerActionInvoker),调用 InvokeAction,这是Action、Filter、模型绑定的核心调度器 ✅ 所有Attribute(AuthorizationFilter、ActionFilter)全部由 ControllerActionInvoker 来收集、排序、执行

5.ControllerActionInvoker 内部执行顺序

    1. 反射读取Controller+Action上所有Filter特性(全局、Controller、Action),排序(Order)
    2. 执行 IAuthorizationFilter(最先!你的CustomAuthenticationAttribute)
  • 不管 IsCheck=false 还是true,OnAuthorization 方法一定会进来

  • IsCheck=false 只是内部if判断,直接return放行,不短路;

  • 如果校验失败,给 filterContext.Result 赋值 → 管道短路,后面所有逻辑不再执行

3.模型绑定 ModelBinder:从QueryString/Form/Header解析参数,赋值给Action参数

4.执行 IActionFilter.OnActionExecuting

5.反射调用Action方法(业务代码)

6.执行 IActionFilter.OnActionExecuted

7.执行 IResultFilter.OnResultExecuting

8.执行 ActionResult.ExecuteResult()

      • ViewResult:找视图引擎Razor,解析cshtml生成html

      • JsonResult:序列化对象写入响应流

9.执行 IResultFilter.OnResultExecuted

10中途抛出未捕获异常 → 触发IExceptionFilter

关键点:Filter不是IIS/HttpApplication管道事件,是ActionInvoker内部的子管道!

三、几个核心对象职责(面试高频)

  • UrlRoutingModule:HttpModule,路由匹配,拦截每一个请求
  • MvcRouteHandler:路由处理器,生产MvcHandler
  • MvcHandler:IHttpHandler,激活Controller、调用Execute
  • DefaultControllerFactory:控制器工厂,反射创建Controller实例(默认每次请求new一个Controller)
  • ControllerActionInvoker:Action调用器,Filter调度中心、模型绑定、反射调用Action(你最关心的自定义Auth Attribute在这里执行)
  • ActionDescriptor / ControllerDescriptor:反射元数据,描述Controller、Action、参数、特性

四、容易踩坑的底层细节

  1. Controller:默认每次请求新建实例,不是单例;Filter Attribute默认单例(同一个实例,反复调用OnAuthorization)
  2. Filter收集顺序:全局Filter → Controller上Attribute → Action上Attribute;Order越小越先执行;Before正向、After反向顺序
  3. TempData:Controller.Execute结束后才保存,在finally里
  4. 路由匹配顺序:RouteTable从上往下匹配,匹配到第一个就停止,路由顺序很关键
相关推荐
学以智用4 小时前
FilterAttribute(ASP.NET Core MVC 过滤器特性)
.net
Jeff-Tsai6 小时前
Day 15:API 契约分层与类型注册表
.net·架构设计·erp·definition-driven
1-1=06 小时前
C# 数据结构和特殊类型
数据结构·c#·.net·.netcore
IT规划师7 小时前
Redis 数据类型全解 - Stream 深度:消费者组、Pending 队列与死信处理(十)
redis·.net
Jeff-Tsai1 天前
Day 14:业务对象的扩展点与重写时机
.net·架构设计·erp·definition-driven
IT规划师1 天前
Redis 数据类型全解 - GEO 地理空间:附近的人、外卖、打车——背后原理与精度陷阱(九)
redis·.net
追逐时光者2 天前
一款基于 .NET 开源、免费的数据库自治诊断平台
后端·.net
追逐时光者2 天前
让 GitHub Copilot 更懂你的 .NET 代码风格:一份精简实用的 Copilot Instructions
后端·.net
Jeff-Tsai2 天前
Day 13:Session 管理与生命周期
.net·架构设计·erp·definition-driven