国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - ASP.NET教程 - 詳解ASP.NET MVC的整個生命周期

詳解ASP.NET MVC的整個生命周期

2021-12-16 14:54可均可可 ASP.NET教程

本文主要介紹了ASP.NET MVC的整個生命周期,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、介紹

我們做開發(fā)的,尤其是做微軟技術(shù)棧的,有一個方向是跳不過去的,那就是MVC開發(fā)。我相信大家,做ASP.NET MVC 開發(fā)有的有很長時間,當(dāng)然,也有剛進入這個行業(yè)的。無論如何,如果有人問你,你知道ASP.NET MVC的生命周期嗎?你知道它的來世今生嗎?你知道它和 ASP.NET WEBFORM 有什么區(qū)別嗎?估計,這些問題,有很多人會答不上來,或者說不清楚。今天,我就把我的理解寫出來,也是對我自己學(xué)習(xí)的一次回顧和總結(jié)吧。當(dāng)然,由于本人能力有限,在寫的過程中也可能會有一些錯誤,希望大家多多包涵,當(dāng)然,更希望大家能不靈賜教,我們共同進步。

在開始之前,我們先來說說,ASP.NET Web Form 和 Asp.net MVC 有什么區(qū)別,這里說的區(qū)別,當(dāng)然是本質(zhì)區(qū)別,不是適用語法那個層次的。其實,說起來,ASP.NET WEB FORM 和 ASP.NET MVC 它們兩個沒有本質(zhì)區(qū)別,使用的都是ASP.NET WEB FORM 的管道處理模型,ASP.NET MVC 也是通過擴展 IHttpModule 和 IHttpHandler 來實現(xiàn)的,都是基于 ASP.NET 的 HttpApplication 的管道處理模型擴展的,在這個層面來說,它們是一樣的。當(dāng)然,大家不要抬杠,我說的本質(zhì)區(qū)別都是在這個方面,不同意的勿噴。

有人會問,ASP.NET MVC 和 ASP.NET WEBAPI 它們會有什么不同嗎?好像 WebAPi 能做的,WebMVC都可以完成,第一眼看上去,好像是這樣,但是它們有著本質(zhì)的不同。WebAPI 的處理管道是重新寫過的,不是基于 HTTPApplication 管道擴展的。ASP.NET WEB API 類似專人做專事,它的管道處理模型更高效,并且有了 Restfull 的概念。當(dāng)然,大家如何向了解更細的內(nèi)容,就需要看源碼了。或再說回來,到了 NET CORE 時代,二者又融合管道了。

 

二、MVC生命周期詳述

1、我們既然要說 ASP.NET MVC的生命周期,為了給大家一個整體印象,俗話說,文不如圖,我就貼一張圖,按著箭頭走,相信大家也會不能理解。

詳解ASP.NET MVC的整個生命周期

2、上圖很簡單,大家按著箭頭走,也能理解的差不多。以下是按著我的理解,劃分了4個模塊。

(1)、路由模塊

RouteBase 是對路由規(guī)則的抽象,也就是說,一個 RouteBase 對象,也就代表了一個條 路由規(guī)則。在 ASP.NET MVC 中,有一個唯一的子類實現(xiàn)就是 Route ,它同樣也是路由規(guī)則的代表。我們有了路由規(guī)則,一定會把這個規(guī)則存放在一個地方,這個地方保存了很多路由規(guī)則,這個地方就是 RouteCollection,中文叫“路由集合”,因為這個集合里面包含的就是 RouteBase 對象。

RouteCollection 就是路由集合,用于保存路由規(guī)則對象,它的定義形式:

[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
    public class RouteCollection : Collection<RouteBase>
    {
        private class ReadLockDisposable : IDisposable
        {
            private ReaderWriterLockSlim _rwLock;

            public ReadLockDisposable(ReaderWriterLockSlim rwLock)
            {
                this._rwLock = rwLock;
            }

            void IDisposable.Dispose()
            {
                this._rwLock.ExitReadLock();
            }
        }
          ......

RouteTable 就是路由表,其實它和 RouteCollection 是一樣的。       

public class RouteTable
  {
      private static RouteCollection _instance = new RouteCollection();

      public static RouteCollection Routes
      {
          get
          {
              return RouteTable._instance;
          }
      }
  }

在ASP.NET MVC處理管線中的第一站就是路由模塊。當(dāng)請求到達路由模塊后,ASP.NET MVC 框架就會根據(jù) RouteTable 中配置的路由模板來匹配當(dāng)前請求以獲得對應(yīng)的 Controller 和 Action 信息。具體的匹配過程就是有UrlRoutingModule(System.Web.Routing.UrlRoutingModule)來實現(xiàn)的。如果遇到一個匹配的規(guī)則,就會立刻跳出下面的配置。也就是說,配置過程是有順序的,如果有一個匹配,后面就算有匹配的也不會執(zhí)行的。

namespace System.Web.Routing
{
  [TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
  public class UrlRoutingModule : IHttpModule
  {
      private static readonly object _contextKey = new object();

      private static readonly object _requestDataKey = new object();

      private RouteCollection _routeCollection;

      public RouteCollection RouteCollection
      {
          get
          {
              if (this._routeCollection == null)
              {
                  this._routeCollection = RouteTable.Routes;
              }
              return this._routeCollection;
          }
          set
          {
              this._routeCollection = value;
          }
      }

      protected virtual void Dispose()
      {
      }

      protected virtual void Init(HttpApplication application)
      {
          if (application.Context.Items[UrlRoutingModule._contextKey] != null)
          {
              return;
          }
          application.Context.Items[UrlRoutingModule._contextKey] = UrlRoutingModule._contextKey;
          application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
      }

      private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
      {
          HttpApplication httpApplication = (HttpApplication)sender;
          HttpContextBase context = new HttpContextWrapper(httpApplication.Context);
          this.PostResolveRequestCache(context);
      }

      [Obsolete("This method is obsolete. Override the Init method to use the PostMapRequestHandler event.")]
      public virtual void PostMapRequestHandler(HttpContextBase context)
      {
      }

      public virtual void PostResolveRequestCache(HttpContextBase context)
      {
          RouteData routeData = this.RouteCollection.GetRouteData(context); 第一步匹配路由規(guī)則
          if (routeData == null)
          {
              return;
          }
          IRouteHandler routeHandler = routeData.RouteHandler; 第二步:如有匹配,就找到RouteHandler對象,該類型的實例是:MvcRouteHandler。
          if (routeHandler == null)
          {
              throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.GetString("UrlRoutingModule_NoRouteHandler"), new object[0]));
          }
          if (routeHandler is StopRoutingHandler)
          {
              return;
          }
          RequestContext requestContext = new RequestContext(context, routeData);
          context.Request.RequestContext = requestContext;
          IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);第三步,根據(jù) RouteHandler 對象,找到最終處理請求的 IHttpHandler 的對象,該類型是 MvcHandler
          if (httpHandler == null)
          {
              throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, SR.GetString("UrlRoutingModule_NoHttpHandler"), new object[]
              {
                  routeHandler.GetType()
              }));
          }
          if (!(httpHandler is UrlAuthFailureHandler))
          {
              context.RemapHandler(httpHandler);第四步,有找到的 IHttpHandler 處理請求。
              return;
          }
          if (FormsAuthenticationModule.FormsAuthRequired)
          {
              UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
              return;
          }
          throw new HttpException(401, SR.GetString("Assess_Denied_Description3"));
      }

      void IHttpModule.Dispose()
      {
          this.Dispose();
      }

      void IHttpModule.Init(HttpApplication application)
      {
          this.Init(application);
      }
  }
}

(2)、Controller 創(chuàng)建模塊

經(jīng)過了路由模塊,生成了 RouteData 路由數(shù)據(jù),它包含了根據(jù)路由規(guī)則匹配的 Controller 和 Action。有了路由數(shù)據(jù),需要有處理器來處理請求,這個任務(wù)就交給了 RouteData 的 RouteHandler 屬性,它的類型是 IRouteHandler,它的值就是MvcRouteHandler,MvcRouteHandler 調(diào)用 GetHttpHandler 獲取處理請求的 IHttpHandler 對象,在 MVC 框架中就是 MvcHandler,詳細代碼如下:

namespace System.Web.Mvc
{
  /// <summary>Selects the controller that will handle an HTTP request.</summary>
  public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState
  {
      private struct ProcessRequestState
      {
          internal IAsyncController AsyncController;

          internal IControllerFactory Factory;

          internal RequestContext RequestContext;

          internal void ReleaseController()
          {
              this.Factory.ReleaseController(this.AsyncController);
          }
      }

      [CompilerGenerated]
      [Serializable]
      private sealed class <>c
      {
          public static readonly MvcHandler.<>c <>9 = new MvcHandler.<>c();

          public static BeginInvokeDelegate<MvcHandler.ProcessRequestState> <>9__20_0;

          public static EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> <>9__20_1;

          public static Func<KeyValuePair<string, object>, bool> <>9__26_0;

          internal IAsyncResult <BeginProcessRequest>b__20_0(AsyncCallback asyncCallback, object asyncState, MvcHandler.ProcessRequestState innerState)
          {
              IAsyncResult result;
              try
              {
                  result = innerState.AsyncController.BeginExecute(innerState.RequestContext, asyncCallback, asyncState);
              }
              catch
              {
                  innerState.ReleaseController();
                  throw;
              }
              return result;
          }

          internal void <BeginProcessRequest>b__20_1(IAsyncResult asyncResult, MvcHandler.ProcessRequestState innerState)
          {
              try
              {
                  innerState.AsyncController.EndExecute(asyncResult);
              }
              finally
              {
                  innerState.ReleaseController();
              }
          }

          internal bool <RemoveOptionalRoutingParameters>b__26_0(KeyValuePair<string, object> entry)
          {
              return entry.Value == UrlParameter.Optional;
          }
      }

      private static readonly object _processRequestTag = new object();

      internal static readonly string MvcVersion = MvcHandler.GetMvcVersionString();

      /// <summary>Contains the header name of the ASP.NET MVC version.</summary>
      public static readonly string MvcVersionHeaderName = "X-AspNetMvc-Version";

      private ControllerBuilder _controllerBuilder;

      internal ControllerBuilder ControllerBuilder
      {
          get
          {
              if (this._controllerBuilder == null)
              {
                  this._controllerBuilder = ControllerBuilder.Current;
              }
              return this._controllerBuilder;
          }
          set
          {
              this._controllerBuilder = value;
          }
      }

      /// <summary>Gets or sets a value that indicates whether the MVC response header is disabled.</summary>
      /// <returns>true if the MVC response header is disabled; otherwise, false.</returns>
      public static bool DisableMvcResponseHeader
      {
          get;
          set;
      }

      /// <summary>Gets a value that indicates whether another request can use the <see cref="T:System.Web.IHttpHandler" /> instance.</summary>
      /// <returns>true if the <see cref="T:System.Web.IHttpHandler" /> instance is reusable; otherwise, false.</returns>
      protected virtual bool IsReusable
      {
          get
          {
              return false;
          }
      }

      /// <summary>Gets the request context.</summary>
      /// <returns>The request context.</returns>
      public RequestContext RequestContext
      {
          get;
          private set;
      }

      /// <summary>Gets a value that indicates whether another request can use the <see cref="T:System.Web.IHttpHandler" /> instance.</summary>
      /// <returns>true if the <see cref="T:System.Web.IHttpHandler" /> instance is reusable; otherwise, false.</returns>
      bool IHttpHandler.IsReusable
      {
          get
          {
              return this.IsReusable;
          }
      }

      /// <summary>Initializes a new instance of the <see cref="T:System.Web.Mvc.MvcHandler" /> class.</summary>
      /// <param name="requestContext">The request context.</param>
      /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestContext" /> parameter is null.</exception>
      public MvcHandler(RequestContext requestContext)
      {
          if (requestContext == null)
          {
              throw new ArgumentNullException("requestContext");
          }
          this.RequestContext = requestContext;
      }

      /// <summary>Adds the version header by using the specified HTTP context.</summary>
      /// <param name="httpContext">The HTTP context.</param>
      protected internal virtual void AddVersionHeader(HttpContextBase httpContext)
      {
          if (!MvcHandler.DisableMvcResponseHeader)
          {
              httpContext.Response.AppendHeader(MvcHandler.MvcVersionHeaderName, MvcHandler.MvcVersion);
          }
      }

      /// <summary>Called by ASP.NET to begin asynchronous request processing.</summary>
      /// <returns>The status of the asynchronous call.</returns>
      /// <param name="httpContext">The HTTP context.</param>
      /// <param name="callback">The asynchronous callback method.</param>
      /// <param name="state">The state of the asynchronous object.</param>
      protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state)
      {
          HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
          return this.BeginProcessRequest(httpContext2, callback, state);
      }

      /// <summary>Called by ASP.NET to begin asynchronous request processing using the base HTTP context.</summary>
      /// <returns>The status of the asynchronous call.</returns>
      /// <param name="httpContext">The HTTP context.</param>
      /// <param name="callback">The asynchronous callback method.</param>
      /// <param name="state">The state of the asynchronous object.</param>
      protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
      {
          IController controller;
          IControllerFactory factory;
          this.ProcessRequestInit(httpContext, out controller, out factory);
          IAsyncController asyncController = controller as IAsyncController;
          if (asyncController != null)
          {
              BeginInvokeDelegate<MvcHandler.ProcessRequestState> arg_51_0;
              if ((arg_51_0 = MvcHandler.<>c.<>9__20_0) == null)
              {
                  arg_51_0 = (MvcHandler.<>c.<>9__20_0 = new BeginInvokeDelegate<MvcHandler.ProcessRequestState>(MvcHandler.<>c.<>9.<BeginProcessRequest>b__20_0));
              }
              BeginInvokeDelegate<MvcHandler.ProcessRequestState> beginDelegate = arg_51_0;
              EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> arg_71_0;
              if ((arg_71_0 = MvcHandler.<>c.<>9__20_1) == null)
              {
                  arg_71_0 = (MvcHandler.<>c.<>9__20_1 = new EndInvokeVoidDelegate<MvcHandler.ProcessRequestState>(MvcHandler.<>c.<>9.<BeginProcessRequest>b__20_1));
              }
              EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> endDelegate = arg_71_0;
              MvcHandler.ProcessRequestState invokeState = new MvcHandler.ProcessRequestState
              {
                  AsyncController = asyncController,
                  Factory = factory,
                  RequestContext = this.RequestContext
              };
              SynchronizationContext synchronizationContext = SynchronizationContextUtil.GetSynchronizationContext();
              return AsyncResultWrapper.Begin<MvcHandler.ProcessRequestState>(callback, state, beginDelegate, endDelegate, invokeState, MvcHandler._processRequestTag, -1, synchronizationContext);
          }
          Action action = delegate
          {
              try
              {
                  controller.Execute(this.RequestContext);
              }
              finally
              {
                  factory.ReleaseController(controller);
              }
          };
          return AsyncResultWrapper.BeginSynchronous(callback, state, action, MvcHandler._processRequestTag);
      }

      /// <summary>Called by ASP.NET when asynchronous request processing has ended.</summary>
      /// <param name="asyncResult">The asynchronous result.</param>
      protected internal virtual void EndProcessRequest(IAsyncResult asyncResult)
      {
          AsyncResultWrapper.End(asyncResult, MvcHandler._processRequestTag);
      }

      private static string GetMvcVersionString()
      {
          return new AssemblyName(typeof(MvcHandler).Assembly.FullName).Version.ToString(2);
      }

      /// <summary>Processes the request by using the specified HTTP request context.</summary>
      /// <param name="httpContext">The HTTP context.</param>
      protected virtual void ProcessRequest(HttpContext httpContext)
      {
          HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);
          this.ProcessRequest(httpContext2);
      }

      /// <summary>Processes the request by using the specified base HTTP request context.</summary>
      /// <param name="httpContext">The HTTP context.</param>
      protected internal virtual void ProcessRequest(HttpContextBase httpContext)
      {
          IController controller;
          IControllerFactory controllerFactory;
          this.ProcessRequestInit(httpContext, out controller, out controllerFactory);
          try
          {
              controller.Execute(this.RequestContext);
          }
          finally
          {
              controllerFactory.ReleaseController(controller);
          }
      }

      private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
      {
          HttpContext current = HttpContext.Current;
          if (current != null)
          {
              bool? flag = ValidationUtility.IsValidationEnabled(current);
              bool flag2 = true;
              if (flag.GetValueOrDefault() == flag2 & flag.HasValue)
              {
                  ValidationUtility.EnableDynamicValidation(current);
              }
          }
          this.AddVersionHeader(httpContext);
          this.RemoveOptionalRoutingParameters();
          string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
          factory = this.ControllerBuilder.GetControllerFactory();
          controller = factory.CreateController(this.RequestContext, requiredString);
          if (controller == null)
          {
              throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[]
              {
                  factory.GetType(),
                  requiredString
              }));
          }
      }

      private void RemoveOptionalRoutingParameters()
      {
          IDictionary<string, object> arg_2F_0 = this.RequestContext.RouteData.Values;
          Func<KeyValuePair<string, object>, bool> arg_2F_1;
          if ((arg_2F_1 = MvcHandler.<>c.<>9__26_0) == null)
          {
              arg_2F_1 = (MvcHandler.<>c.<>9__26_0 = new Func<KeyValuePair<string, object>, bool>(MvcHandler.<>c.<>9.<RemoveOptionalRoutingParameters>b__26_0));
          }
          arg_2F_0.RemoveFromDictionary(arg_2F_1);
      }

      /// <summary>Enables processing of HTTP Web requests by a custom HTTP handler that implements the <see cref="T:System.Web.IHttpHandler" /> interface.</summary>
      /// <param name="httpContext">An <see cref="T:System.Web.HttpContext" /> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) that are used to service HTTP requests.</param>
      void IHttpHandler.ProcessRequest(HttpContext httpContext)
      {
          this.ProcessRequest(httpContext);
      }

      /// <summary>Called by ASP.NET to begin asynchronous request processing using the base HTTP context.</summary>
      /// <returns>The status of the asynchronous call.</returns>
      /// <param name="context">The HTTP context.</param>
      /// <param name="cb">The asynchronous callback method.</param>
      /// <param name="extraData">The data.</param>
      IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
      {
          return this.BeginProcessRequest(context, cb, extraData);
      }

      /// <summary>Called by ASP.NET when asynchronous request processing has ended.</summary>
      /// <param name="result">The asynchronous result.</param>
      void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
      {
          this.EndProcessRequest(result);
      }
  }
}
HttpRuntime 調(diào)用 IHttpHandler 類型的調(diào)用 ProcessRequest() 方法,用于處理請求。

protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
  IController controller;
  IControllerFactory controllerFactory;
  this.ProcessRequestInit(httpContext, out controller, out controllerFactory);創(chuàng)建 IControllerFactory,并創(chuàng)建 IController 對象。
  try
  {
      controller.Execute(this.RequestContext);執(zhí)行Controller,背后就是調(diào)用相應(yīng)的 Action 方法。
  }
  finally
  {
      controllerFactory.ReleaseController(controller);
  }
}

核心處理請求的方法是ProcessRequestInit(),用于創(chuàng)建 IController 和 IControllerFactory 實例。IControllerFactory 的實際類型是:DefaultControllerFactory,該類型用于創(chuàng)建 IController 類型的實例。

private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
{
  HttpContext current = HttpContext.Current;
  if (current != null)
  {
      bool? flag = ValidationUtility.IsValidationEnabled(current);
      bool flag2 = true;
      if (flag.GetValueOrDefault() == flag2 & flag.HasValue)
      {
          ValidationUtility.EnableDynamicValidation(current);
      }
  }
  this.AddVersionHeader(httpContext);
  this.RemoveOptionalRoutingParameters();
  string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
  factory = this.ControllerBuilder.GetControllerFactory();
  controller = factory.CreateController(this.RequestContext, requiredString);
  if (controller == null)
  {
      throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[]
      {
          factory.GetType(),
          requiredString
      }));
  }
}

以上加紅的代碼就是創(chuàng)建 IController 的實例的邏輯。IController 實例創(chuàng)建完成后,判斷是否實現(xiàn)了 IAsyncController 接口,如果是,就異步執(zhí)行 Controller 方法的調(diào)用,否則就同步執(zhí)行。

protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
{
  IController controller;
  IControllerFactory factory;
  this.ProcessRequestInit(httpContext, out controller, out factory);
  IAsyncController asyncController = controller as IAsyncController; 判讀是否是需要異步執(zhí)行
  if (asyncController != null)異步執(zhí)行
  {
      BeginInvokeDelegate<MvcHandler.ProcessRequestState> arg_51_0;
      if ((arg_51_0 = MvcHandler.<>c.<>9__20_0) == null)
      {
          arg_51_0 = (MvcHandler.<>c.<>9__20_0 = new BeginInvokeDelegate<MvcHandler.ProcessRequestState>(MvcHandler.<>c.<>9.<BeginProcessRequest>b__20_0));
      }
      BeginInvokeDelegate<MvcHandler.ProcessRequestState> beginDelegate = arg_51_0;
      EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> arg_71_0;
      if ((arg_71_0 = MvcHandler.<>c.<>9__20_1) == null)
      {
          arg_71_0 = (MvcHandler.<>c.<>9__20_1 = new EndInvokeVoidDelegate<MvcHandler.ProcessRequestState>(MvcHandler.<>c.<>9.<BeginProcessRequest>b__20_1));
      }
      EndInvokeVoidDelegate<MvcHandler.ProcessRequestState> endDelegate = arg_71_0;
      MvcHandler.ProcessRequestState invokeState = new MvcHandler.ProcessRequestState
      {
          AsyncController = asyncController,
          Factory = factory,
          RequestContext = this.RequestContext
      };
      SynchronizationContext synchronizationContext = SynchronizationContextUtil.GetSynchronizationContext();
      return AsyncResultWrapper.Begin<MvcHandler.ProcessRequestState>(callback, state, beginDelegate, endDelegate, invokeState, MvcHandler._processRequestTag, -1, synchronizationContext);
  }
  Action action = delegate//同步執(zhí)行。
  {
      try
      {
          controller.Execute(this.RequestContext);
      }
      finally
      {
          factory.ReleaseController(controller);
      }
  };
  return AsyncResultWrapper.BeginSynchronous(callback, state, action, MvcHandler._processRequestTag);
}

(3)、Action 執(zhí)行模塊,通過 ControllerActionInvoker 調(diào)用 InvokeAction() 執(zhí)行其方法。Action 方法的執(zhí)行也有2個版本,一個是異步版本,一個是同步版本。由于 ActionInvoker 實現(xiàn)了 IAsyncActionInvoker 接口,所以也是以已方式執(zhí)行。該類型是 AsyncControllerActionInvoker。

A、當(dāng)Controller對象被創(chuàng)建之后,緊接著就會執(zhí)行Controler 對象的 Execute(),其實背后就是調(diào)用 InvokeAction() 方法:

public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
{
  if (controllerContext == null)
  {
      throw new ArgumentNullException("controllerContext");
  }
  if (string.IsNullOrEmpty(actionName) && !controllerContext.RouteData.HasDirectRouteMatch())
  {
      throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
  }
  ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(controllerContext);
  ActionDescriptor actionDescriptor = this.FindAction(controllerContext, controllerDescriptor, actionName);
  if (actionDescriptor != null)
  {
      FilterInfo filters = this.GetFilters(controllerContext, actionDescriptor); 獲取所有過濾器,全局的、控制器的和方法的
      try
      {
          AuthenticationContext authenticationContext = this.InvokeAuthenticationFilters(controllerContext, filters.AuthenticationFilters, actionDescriptor);認證過濾器的執(zhí)行。
          if (authenticationContext.Result != null)
          {
              AuthenticationChallengeContext authenticationChallengeContext = this.InvokeAuthenticationFiltersChallenge(controllerContext, filters.AuthenticationFilters, actionDescriptor, authenticationContext.Result);
              this.InvokeActionResult(controllerContext, authenticationChallengeContext.Result ?? authenticationContext.Result);
          }
          else
          {
              AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor);授權(quán)過濾器的執(zhí)行。
              if (authorizationContext.Result != null)
              {
                  AuthenticationChallengeContext authenticationChallengeContext2 = this.InvokeAuthenticationFiltersChallenge(controllerContext, filters.AuthenticationFilters, actionDescriptor, authorizationContext.Result);
                  this.InvokeActionResult(controllerContext, authenticationChallengeContext2.Result ?? authorizationContext.Result);
              }
              else
              {
                  if (controllerContext.Controller.ValidateRequest)
                  {
                      ControllerActionInvoker.ValidateRequest(controllerContext);
                  }
                  IDictionary<string, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor); 獲取方法執(zhí)行參數(shù)。
                  ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameterValues); 執(zhí)行action,同時執(zhí)行執(zhí)行方法前后的 IAcctionFilter
                  AuthenticationChallengeContext authenticationChallengeContext3 = this.InvokeAuthenticationFiltersChallenge(controllerContext, filters.AuthenticationFilters, actionDescriptor, actionExecutedContext.Result);
                  this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, authenticationChallengeContext3.Result ?? actionExecutedContext.Result); 執(zhí)行 ActionResult,同時執(zhí)行方法前后的 IResultFilter
              }
          }
      }
      catch (ThreadAbortException)
      {
          throw;
      }
      catch (Exception exception)
      {
          ExceptionContext exceptionContext = this.InvokeExceptionFilters(controllerContext, filters.ExceptionFilters, exception);
          if (!exceptionContext.ExceptionHandled)
          {
              throw;
          }
          this.InvokeActionResult(controllerContext, exceptionContext.Result);//異常過濾器的執(zhí)行。
      }
      return true;
  }
  return false;
}

B、當(dāng)選擇完合適的Action后,接著就是 ModelBinder(默認是System.Web.Mvc.DefaultModelBinder),它會從http請求的參數(shù)中提取數(shù)據(jù)并實現(xiàn)類型轉(zhuǎn)換,數(shù)據(jù)校驗(例如是否必填,數(shù)據(jù)格式等)以及是否自動裝配到action方法的參數(shù)中System.Web.Mvc.DefaultModelBinder

protected virtual IDictionary<string, object> GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
  Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
  ParameterDescriptor[] parameters = actionDescriptor.GetParameters();
  for (int i = 0; i < parameters.Length; i++)
  {
      ParameterDescriptor parameterDescriptor = parameters[i];
      dictionary[parameterDescriptor.ParameterName] = this.GetParameterValue(controllerContext, parameterDescriptor);
  }
  return dictionary;
}


protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
{
  Type parameterType = parameterDescriptor.ParameterType;
  IModelBinder arg_92_0 = this.GetModelBinder(parameterDescriptor);
  IValueProvider valueProvider = controllerContext.Controller.ValueProvider;
  string modelName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
  Predicate<string> propertyFilter = ControllerActionInvoker.GetPropertyFilter(parameterDescriptor);
  ModelBindingContext bindingContext = new ModelBindingContext
  {
      FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null,
      ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),
      ModelName = modelName,
      ModelState = controllerContext.Controller.ViewData.ModelState,
      PropertyFilter = propertyFilter,
      ValueProvider = valueProvider
  };
  return arg_92_0.BindModel(controllerContext, bindingContext) ?? parameterDescriptor.DefaultValue;
}

C、Authentication Filter是mvc5中新增的一個Filter,它會先于authorization filter執(zhí)行,目的是對訪問用戶的認證。在MVC5之前,認證和授權(quán)都是通過authorization filter來實現(xiàn)的,但現(xiàn)在這2個操作就分開來了,各自管各自嘍。

AuthenticationContext authenticationContext = this.InvokeAuthenticationFilters(controllerContext, filters.AuthenticationFilters, actionDescriptor);
          if (authenticationContext.Result != null)
          {
              AuthenticationChallengeContext authenticationChallengeContext = this.InvokeAuthenticationFiltersChallenge(controllerContext, filters.AuthenticationFilters, actionDescriptor, authenticationContext.Result);
              this.InvokeActionResult(controllerContext, authenticationChallengeContext.Result ?? authenticationContext.Result);
          }

D、Action filters有2個方法OnActionExecuting和OnActionExecuted分別在action執(zhí)行前后執(zhí)行。我們也可以通過實現(xiàn)IActionFilter接口來實現(xiàn)你個性化的過濾機制

protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
  ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
  Func<ActionExecutedContext> seed = () => new ActionExecutedContext(controllerContext, actionDescriptor, false, null)
  {
      Result = this.InvokeActionMethod(controllerContext, actionDescriptor, parameters)
  };
  return filters.Reverse<IActionFilter>().Aggregate(seed, (Func<ActionExecutedContext> next, IActionFilter filter) => () => ControllerActionInvoker.InvokeActionMethodFilter(filter, preContext, next))();
}

E、接下來就是執(zhí)行我們平時在Action方法中寫的代碼了(根據(jù)請求相應(yīng)結(jié)果)

protected virtual ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
   object actionReturnValue = actionDescriptor.Execute(controllerContext, parameters);
   return this.CreateActionResult(controllerContext, actionDescriptor, actionReturnValue);
}

(4)、ActionResult 執(zhí)行模塊。

A、在 ActionResult 執(zhí)行前后,仍然會有一個filter(IResultFilter),同樣的,通過實現(xiàn) IResultFilter 接口你可以定制自己的過濾邏輯。

namespace System.Web.Mvc
{
  /// <summary>Defines the methods that are required for a result filter.</summary>
  public interface IResultFilter
  {
      /// <summary>Called before an action result executes.</summary>
      /// <param name="filterContext">The filter context.</param>
      void OnResultExecuting(ResultExecutingContext filterContext);

      /// <summary>Called after an action result executes.</summary>
      /// <param name="filterContext">The filter context.</param>
      void OnResultExecuted(ResultExecutedContext filterContext);
  }
}

B、ActionResult 就是把處理的用戶請求結(jié)果返回。因此 ViewResult, PartialViewResult, RedirectToRouteResult, RedirectResult, ContentResult, JsonResult, FileResult and EmptyResult就是具體的返回類型。

C、上面的返回類型可以大致分為2類:ViewResult 和非ViewResult。對于需要生成html頁面給客戶端的劃到ViewResult,而其他的例如返回文本,json數(shù)據(jù)等則劃分到非ViewResult,對于非ViewResult直接返回就可以了。

View的初始化和渲染呈現(xiàn)

A、對于 ViewResult 最終是由合適的 View Engine 通過調(diào)用 IView 的 Render() 方法來渲染的:

namespace System.Web.Mvc
{
  /// <summary>Defines the methods that are required for a view engine.</summary>
  public interface IViewEngine
  {
      /// <summary>Finds the specified partial view by using the specified controller context.</summary>
      /// <returns>The partial view.</returns>
      /// <param name="controllerContext">The controller context.</param>
      /// <param name="partialViewName">The name of the partial view.</param>
      /// <param name="useCache">true to specify that the view engine returns the cached view, if a cached view exists; otherwise, false.</param>
      ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);

      /// <summary>Finds the specified view by using the specified controller context.</summary>
      /// <returns>The page view.</returns>
      /// <param name="controllerContext">The controller context.</param>
      /// <param name="viewName">The name of the view.</param>
      /// <param name="masterName">The name of the master.</param>
      /// <param name="useCache">true to specify that the view engine returns the cached view, if a cached view exists; otherwise, false.</param>
      ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);

      /// <summary>Releases the specified view by using the specified controller context.</summary>
      /// <param name="controllerContext">The controller context.</param>
      /// <param name="view">The view.</param>
      void ReleaseView(ControllerContext controllerContext, IView view);
  }
}

namespace System.Web.Mvc
{
  /// <summary>Defines the methods that are required for a view.</summary>
  public interface IView
  {
      /// <summary>Renders the specified view context by using the specified the writer object.</summary>
      /// <param name="viewContext">The view context.</param>
      /// <param name="writer">The writer object.</param>
      void Render(ViewContext viewContext, TextWriter writer);
  }
}

B、整個處理過程是由 IViewEngine 來實現(xiàn)的。ASP.NET MVC 默認提供 WebForm(.aspx)和 Razor(.cshtml) 模板引擎,你可以通過實現(xiàn) IViewEngine 接口來實現(xiàn)自己的 ViewEngine,然后在Application_Start方法中做如下注冊:

protected void Application_Start()
{
//移除所有的View引擎包括Webform和Razor
ViewEngines.Engines.Clear();
//注冊你自己的View引擎

ViewEngines.Engines.Add(new CustomViewEngine()); 
}

C、最后,Html Helpers將幫我們生成 input 標(biāo)簽,基于AJAX的 form 等等。

(5)、作為總結(jié),將每個節(jié)點主要的代碼類貼出來。

這就是整個流程的代碼節(jié)點,有些是同步執(zhí)行,有些是異步執(zhí)行,把握關(guān)鍵點,我這里只是謝了一個大概。

UrlRoutingModule-----RouteCollection.GetRouteData(context)----->IRouteHandler routeHandler = routeData.RouteHandler------》IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext)-----》context.RemapHandler(httpHandler)------->MvcHandler------->ProcessRequest()------>ProcessRequestInit()--------》IController------>controller.Execute(this.RequestContext)-------->ControllerActionInvoker------->InvoleAction()--------->InvoleActionMethod()------->InvoleActionReslt()

 

三、結(jié)束

今天就到這里了,東西雖然不多,但是也寫了2個多小時。今天就算自己有學(xué)習(xí)了一邊,大家一定要好好的把握這個流程,對于解決程序中的問題,擴展框架都有很大的好處。我們作為程序員的,應(yīng)該要知道其一,也要知道其二。沒事,看看源碼,我們對框架和我們自己的代碼有更深的了解。當(dāng)然,這樣做也是有代價的,需要更多的時間去支持,我相信我們的付出是值得。不忘初心,繼續(xù)努力。老天不會辜負努力的人。

到此這篇關(guān)于詳解ASP.NET MVC的整個生命周期的文章就介紹到這了,更多相關(guān)ASP.NET MVC 生命周期內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://www.cnblogs.com/PatrickLiu/p/15175388.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲一区精品在线 | 成人a视频在线观看 | 日韩午夜电影 | 久久国产成人 | 高清18麻豆 | 精品久久免费 | 国产高清av在线播放 | 国产成人三区 | 羞羞的视频 | 国产剧情一区二区 | 欧美精品一二区 | 国产精品免费一区二区三区四区 | 欧美精品一区二区三区一线天视频 | 一级黄色一级毛片 | 欧美视频一区二区三区 | 草久久| 日韩欧美在线观看 | 日本黄色大片免费 | 天天干天天射天天操 | 久久这里只有精品免费 | 999精品视频 | 日韩欧美二区 | 欧美日本精品 | 亚洲精品国产综合99久久夜夜嗨 | 国产老头老太作爱视频 | 国产精品久久电影观看 | 久久大陆 | 激情一级片 | 日韩大片 | 国产日韩一区二区 | 精品综合在线 | 国产精品 日韩 | 成人精品一区二区三区 | 成年人黄色免费网站 | 亚洲精品视频免费 | 国产一级黄色大片 | 色黄视频 | 奇米一区二区三区 | 久久久久国产精品免费免费搜索 | 成人短视频在线 | 日本人在线观看 |