MVC框架的原理详解

MVC框架的原理详解

前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎。这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之处,还希望大家斧正,博主感激不尽!

一、MVC原理解析

最近园子里Asp.Net Core火了一阵,不管微软的开源动作有多么迟缓,还是希望微软能够给力一次。作为Core的主要Web框架——MVC,虽然已经开源,但是读起来着实费劲,并且感觉很多核心部件都找不到。于是只能通过Reflector去反编译MVC5的组件以及参考博客园Fish Li等大神的文章去学习下MVC5的原理。
————————————————
Asp.Net Core MVC的开源地址:https://github.com/aspnet/Mvc
Asp.net MVC的开源地址:http://aspnetwebstack.codeplex.com/SourceControl/latest

1、MVC原理

之前的文章有介绍MVC的路由机制,其实路由机制算是MVC的原理的核心之一。在此我们还是要不厌其烦再来谈谈整个过程,因为这是理解MVC原理不可逾越的鸿沟。当我们收到一个URL的请求时,服务端收到请求,主要经历以下几个步骤:

1.请求被UrlRoutingModule部件拦截
2.封装请求上下文HttpContext,成为HttpContextWrapper对象。
3.根据当前的HttpContext,从Routes集合中得到与当前请求URL相符合的RouteData对象。
4.将RouteData与HttpContext请求封装成一个RequestContext对象。
5.根据RequestContext对象,从RouteData的RouteHandler中获取IHttpHandler(MVC里面会有一个IHttpHandler的实现类MvcHandler)。
6.执行IHttpHandler(MvcHandler),然后就是通过反射激活具体的controller,执行具体的action。

二、HttpHandler

上文说过MvcHandler是继承至IHttpHandler接口的!为什么这里大标题会用HttpHandler而不是MvcHandler呢?因为博主觉得,HttpHandler实在是太重要了,首先得理解了HttpHandler这么一个大的东西,然后再来看具体的MvcHandler才有意义。

1、HttpHandler、IHttpHandler、MvcHandler的说明

1.HttpHandler指所有实现IHttpHandler接口一类类型的统称,它是一个大的称谓。这些类型有一个共同的功能,那就是可以用来处理Http请求。
2.IHttpHandler是微软定义的一类接口,用来约束所有能够处理Http请求的类型的接口规则。
3.MvcHandler是Mvc里面实现IHttpHandler接口的类型,也就是说,MvcHandler是Mvc里面处理Http请求的类型。
总而言之,HttpHandler只是一个逻辑称谓,它并不具体存在。而IHttpHandler和MvcHandler是.net framework里面具体存在的接口和实现类,是前者的表现形式。

2、IHttpHandler解析

2.1、Asp.net管线事件简易说明

在处理该请求时将由 HttpApplication 类执行以下事件。 希望扩展 HttpApplication 类的开发人员尤其需要注意这些事件。

  1. 对请求进行验证,将检查浏览器发送的信息,并确定其是否包含潜在恶意标记。 有关更多信息,请参见 ValidateRequest 和脚本侵入概述。
  2. 如果已在 Web.config 文件的 UrlMappingsSection 节中配置了任何 URL,则执行 URL 映射。
  3. 引发 BeginRequest 事件。
  4. 引发 AuthenticateRequest 事件。
  5. 引发 PostAuthenticateRequest 事件。
  6. 引发 AuthorizeRequest 事件。
  7. 引发 PostAuthorizeRequest 事件。
  8. 引发 ResolveRequestCache 事件。
  9. 引发 PostResolveRequestCache 事件。
  10. 根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理。 如果该请求针对从 Page 类派生的对象(页),并且需要对该页进行编译,则 ASP.NET 会在创建该页的实例之前对其进行编译。
  11. 引发 PostMapRequestHandler 事件。
  12. 引发 AcquireRequestState 事件。
  13. 引发 PostAcquireRequestState 事件。
  14. 引发 PreRequestHandlerExecute 事件。
  15. 为该请求调用合适的 IHttpHandler 类的 ProcessRequest 方法(或异步版 IHttpAsyncHandler.BeginProcessRequest)。 例如,如果该请求针对某页,则当前的页实例将处理该请求。
  16. 引发 PostRequestHandlerExecute 事件。
  17. 引发 ReleaseRequestState 事件。
  18. 引发 PostReleaseRequestState 事件。
  19. 如果定义了 Filter 属性,则执行响应筛选。
  20. 引发 UpdateRequestCache 事件。
  21. 引发 PostUpdateRequestCache 事件。
  22. 引发 EndRequest 事件。
  23. 引发 PreSendRequestHeaders 事件。
  24. 引发 PreSendRequestContent 事件。

这里不可能把每个管线事件将清楚,但是在整个管线事件中,有两个重要的角色就是HttpHandler和HttpModule。在这些事件中,第10个事件【根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理】 是HttpHandler创建的地方。

2.2、Asp.net中常见的HttpHandler类型

首先还是来看看IHttpHandler的定义

public interface IHttpHandler
{
   
    // 定义一个处理当前http请求的方法
    void ProcessRequest(HttpContext context);

    // 指示当前实例是否可以再次使用
    bool IsReusable {
    get; }
}

接口的定义很简单,ProcessRequest()方法里面传一个当前请求的上下文对象去处理当前的http请求。

为了处理异步请求,Framework里面还定义了一个异步的IHttpHandler接口:

public interface IHttpAsyncHandler : IHttpHandler
{
   
    // Methods
    IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
    void EndProcessRequest(IAsyncResult result);
}

接口的两个方法应该也不难理解。

我们已经说了,HttpHandler的主要作用是处理http请求,原来在做webform的时候应该都写过后缀ashx的一般处理程序吧,这个一般处理程序就是通过实现IHttpHandler接口去实现的。我们是否曾经也写过类似这样的代码,新建一个TestHttpHandler.ashx文件,代码如下:

public class TestHttpHandler : IHttpHandler
    {
   

        public void ProcessRequest(HttpContext context)
        {
   
            context.Response.ContentType = "text/plain";

            var username = context.Request.QueryString["username"];
            var password = context.Request.QueryString["password"];
            if (username == "admin" && password == "admin")
            {
   
                context.Response.Write("用户admin登录成功");
            }
            else
            {
   
                context.Response.Write("用户名或者密码错误");
            }
        }

        public bool IsReusable
        {
   
            get
            {
   
                return false;
            }
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值