ASP.NET MVC涉及到的5個同步與非同步二
Action方法的執行具有兩種基本的形式,即同步執行和非同步執行,而在ASP.NETMVC的整個體系中涉及到很多同步/非同步的執行方式,雖然在前面相應的文章中已經對此作了相應的介紹,為了讓讀者對此有一個整體的瞭解,我們來做一個總結性的論述。[本文已經同步到《How ASP.NET MVC Works?》中]
目錄
一、MvcHandler的同步於非同步
二、Controller的同步與非同步
三、ActionInvoker的同步與非同步
四、ControllerDescriptor的同步與非同步
五、ActionDescriptor的同步與非同步
一、MvcHandler的同步與非同步
對於ASP.NET MVC應用來說,MvcHandler是最終用於處理請求的HttpHandler,它是通過UrlRoutingModule這個實現了URL路由的HttpModule被動態對映到相應的請求的。MvcHandler藉助於ControllerFactory啟用並執行目標Controller,並在執行結束後負責對啟用的Controller進行釋放,相關的內容請參與本書的第3章“Controller的啟用”。如下面的程式碼片斷所示,MvcHandler同時實現了IHttpHandler和IHttpAsyncHandler介面,所以它總是呼叫BeginProcessRequest/EndProcessRequest方法以非同步的方式來處理請求
1: public class MvcHandler : IHttpAsyncHandler, IHttpHandler, ...
2: {
3: //其他成員
4: IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
5: void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result);
6:void IHttpHandler.ProcessRequest(HttpContext httpContext);
7: }
二、Controller的同步與非同步
Controller也具有同步與非同步兩個版本,它們分別實現了具有如下定義的兩個介面IController和IAsyncController。當啟用的Controller物件在MvcHandler的BeginProcessRequest方法中是按照這樣的方式執行的:如果Controller的型別實現了IAsyncController介面,則呼叫BeginExecute/EndExecute方法以非同步的方式執行Controller;否則Controller的執行通過呼叫Execute方法以同步方式執行。
1: public interface IController
2: {
3: void Execute(RequestContext requestContext);
4: }
5: public interface IAsyncController : IController
6: {
7: IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state);
8: void EndExecute(IAsyncResult asyncResult);
9: }
預設情況下通過Visual Studio的嚮導建立的Controller型別是抽象型別Controller的子類。如下面的程式碼片斷所示,Controller同時實現了IController和IAsyncController這兩個介面,所以當MvcHandler進行請求處理時總是以非同步的方式來執行Controller。
1: public abstract class Controller : ControllerBase, IController, IAsyncController, ...
2: {
3: //其他成員
4: protected virtual bool DisableAsyncSupport
5: {
6: get{return false;}
7: }
8: }
但是Controller型別具有一個受保護的只讀屬性DisableAsyncSupport用於表示是否禁用對非同步執行的支援。在預設情況下,該屬性值為False,所以預設情況下是支援Controller的非同步執行的。如果我們通過重寫該屬性將值設定為True,那麼Controller將只能以同步的方式執行。具體的實現邏輯體現在如下的程式碼片斷中:BeginExecute方法在DisableAsyncSupport屬性為True的情況下通過呼叫Execute方法(該方法會呼叫一個受保護的虛方法ExecuteCore最終對Controller進行同步執行);否則通過呼叫BeginExecuteCore/EndExecuteCore以非同步方式執行Controller。
1: public abstract class Controller: ...
2: {
3: //其他成員
4: protected virtual IAsyncResult BeginExecute(RequestContext requestContext,
5: AsyncCallback callback, object state)
6: {
7: if (this.DisableAsyncSupport)
8: {
9: //通過呼叫Execute方法同步執行Controller
10: }
11: else
12: {
13: //通過呼叫BeginExecuteCore/EndExecuteCore方法非同步執行Controller
14: }
15: }
16: protected override void ExecuteCore();
17: protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state);
18: protected virtual void EndExecuteCore(IAsyncResult asyncResult);
19: }
三、 ActionInvoker的同步與非同步
包括Model繫結與驗證的整個Action的執行通過一個名為ActionInvoker的元件來完成,而它同樣具有同步和非同步兩個版本,分別實現了介面IActionInvoker和IAsyncActionInvoker。如下面的程式碼片斷所示,這兩個介面分別通過InvokeAction和BeginInvokeAction/EndInvokeAction方法以同步和非同步的方式執行Action。抽象類Controller中具有一個ActionInvoker屬性用於設定和返回用於執行自身Action的ActionInvoker物件,而該物件最終是通過受保護需方法CreateActionInvoker建立的。
1: public interface IActionInvoker
2: {
3: bool InvokeAction(ControllerContext controllerContext, string actionName);
4: }
5:
6: public interface IAsyncActionInvoker : IActionInvoker
7: {
8: IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state);
9: bool EndInvokeAction(IAsyncResult asyncResult);
10: }
11:
12: public abstract class Controller
13: {
14: //其它成員
15: public IActionInvoker ActionInvoker { get; set; }
16: protected virtual IActionInvoker CreateActionInvoker()
17: }
ASP.NET MVC真正用於Action方法同步和非同步執行的ActionInvoker分別是ControllerActionInvoker和AsyncControllerActionInvoker。如下面的程式碼片斷所示,ControllerActionInvoker定義了一個受保護的方法GetControllerDescriptor用於根據指定的Controller上下文獲取相應的ControllerDescriptor,它的子類AsyncControllerActionInvoker對這個方法進行了重寫。
1: public class ControllerActionInvoker : IActionInvoker
2: {
3: //其它成員
4: protected virtual ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext);
5: }
6:
7: public class AsyncControllerActionInvoker : ControllerActionInvoker,IAsyncActionInvoker, IActionInvoker
8: {
9: //其它成員
10: protected override ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext);
11: }
我們所有要了解的是在預設情況下(沒有對Controller型別的ActionInvoker屬性進行顯式設定)採用的ActionInvoker型別是哪個。ASP.NET MVC對Conroller採用的ActionInvoker型別的選擇機制是這樣的:
- 通過當前的DependencyResolver以IAsyncActionInvoker介面去獲取註冊的ActionInvoker,如果返回物件不為Null,則將其作為預設的ActionInvoker。
- ·通過當前的DependencyResolver以IActionInvoker介面去獲取註冊的ActionInvoker,如果返回物件不為Null,則將其作為預設的ActionInvoker。
- 建立AsyncControllerActionInvoker物件作為預設的ActionInvoker。
在預設的情況下,當前的DependencyResolver直接通過對指定的型別進行反射來提供對應的例項物件,所以對於前面兩個步驟返回的物件均為Null,所以預設創建出來的ActionInvoker型別為AsyncControllerActionInvoker。我們可以通過如下一個簡單的例項來驗證這一點。在通過Visual Studio的ASP.NET MVC專案模板建立的空Web應用中,我們建立瞭如下一個預設的HomeController,在Action方法Index中直接通過ContentResult將ActionInvoker屬性的型別名稱呈現出來。
1: public class HomeController : Controller
2: {
3: public ActionResult Index()
4: {
5: return Content("預設ActionInvoker型別:" + this.ActionInvoker.GetType().FullName);
6: }
7: }
當執行該Web應用時,會在瀏覽器上產生如下的輸出結果,我們可以清楚地看到預設採用的ActionInvoker型別正是AsyncControllerActionInvoker。
1: 預設ActionInvoker型別:System.Web.Mvc.Async.AsyncControllerActionInvoker
為了進一步驗證基於DependencyResolver對ActionInvoker的提供機制,我們將《ASP.NET MVC Controller啟用系統詳解:IoC的應用[下篇]》建立的基於Ninject的自定義NinjectDependencyResolver應用在這裡。如下面的程式碼片斷所示,在初始化NinjectDependencyResolver的時候,我們將IActionInvoker和IAsyncActionInvoker影射到兩個自定義ActionInvoker型別,即FooActionInvoker和FooAsyncActionInvoker,它們分別繼承自ControllerActionInvoker和AsyncControllerActionInvoker。
1: public class NinjectDependencyResolver : IDependencyResolver
2: {
3: public IKernel Kernel { get; private set; }
4: public NinjectDependencyResolver()
5: {
6: this.Kernel = new StandardKernel();
7: AddBindings();
8: }
9: private void AddBindings()
10: {
11: this.Kernel.Bind<IActionInvoker>().To<FooActionInvoker>();
12: this.Kernel.Bind<IAsyncActionInvoker>().To<FooAsyncActionInvoker>();
13: }
14: public object GetService(Type serviceType)
15: {
16: return this.Kernel.TryGet(serviceType);
17: }
18: public IEnumerable<object> GetServices(Type serviceType)
19: {
20: return this.Kernel.GetAll(serviceType);
21: }
22: }
23: public class FooActionInvoker : ControllerActionInvoker
24: {}
25: public class FooAsyncActionInvoker : AsyncControllerActionInvoker
26: {}
在Global.asax中對NinjectDependencyResolver進行註冊後執行我們的程式,會在瀏覽器中得到如下的輸出結果。IAsyncActionInvoker和FooAsyncActionInvoker進行了影射,NinjectDependencyResolver可以通過IAsyncActionInvoker提供一個FooAsyncActionInvoker例項。
1: 預設ActionInvoker型別:Artech.Mvc.FooAsyncActionInvoker
現在我們對NinjectDependencyResolver的定義稍加修改,將針對IAsyncActionInvoker介面的型別影射刪除,只保留針對IActionInvoker的對映。
1: public class NinjectDependencyResolver : IDependencyResolver
2: {
3: //其它成員
4: private void AddBindings()
5: {
6: this.Kernel.Bind<IActionInvoker>().To<FooActionInvoker>();
7: //this.Kernel.Bind<IAsyncActionInvoker>().To<FooAsyncActionInvoker>();
相關推薦
ASP.NET MVC涉及到的5個同步與非同步二
Action方法的執行具有兩種基本的形式,即同步執行和非同步執行,而在ASP.NETMVC的整個體系中涉及到很多同步/非同步的執行方式,雖然在前面相應的文章中已經對此作了相應的介紹,為了讓讀者對此有一個整體的瞭解,我們來做一個總結性的論述。[本文已經同步到《How
ASP.NET MVC 入門5、View與ViewData
本系列文章基於ASP.NET MVC Preview5.
view在MVC模式中與使用者進行最直接的接觸,它負責資料的呈現。這裡要注意一點就是,view只是負責資料的呈現,所以我們應該要儘量讓view中不涉及業務邏輯的處理。
我們來新增一個Blog首頁的view。在安裝了ASP.NET MVC後,我們在新
ASP.NET MVC Identity 兩個多個連接字符串問題解決一例
fail conn init led user asp identity 字符串 initial 按照ASP.NET MVC Identity建立了一個用戶權限管理模塊,由於還要加自己已有的數據庫,所以建立了一個實體模型,建立了之後,發現登錄不了:
一直顯示“Login i
ASP.NET MVC編程——錯誤處理與日記
CP 引用 args context mvc4 strong gpo pub family ASP.NET MVC的錯誤處理應考慮到這幾個方面:模型綁定期間發生的錯誤,未能路由到指定操作,針對控制器的錯誤處理。使用配置文件可以幫助我們處理異常,但是不夠靈活和全面;使用Han
ASP.NET MVC同時支持web與webapi模式
mod AR center 擴展 ica app attr host 版本 原文地址:https://blog.csdn.net/laymat/article/details/65444701
我們在創建 web mvc項目時是不支持web api的接口方式訪問的,所以我
ASP.NET MVC@model多個對象
type eat ret str idt urn 問題 同時 em1 需求:同時查看一個產品信息和發布會員的信息
方案1:新建ViewModel
方案2:ViewData、ViewBag
方案3:Tuple<obj1,obj2>
在這裏我們使用方
c# ASP.NET MVC模式 WPS的匯入與匯出的實現
前提準備:
1.想要成功進行WPS的匯入與匯出,你得先下載WPS,然後找到etapi.dll檔案(路徑:\Kingsoft\WPS Office\10.1.0.7520\office6),WPS安裝路徑看你們具體的安裝路徑。
2.然後在自己的ASP.NET MVC
asp.net mvc 裡的Url.Action與Url.RenderAction
其實,asp.net mvc 裡的Url.Action與Url.RenderAction,這根本就是兩個不同類的東西,不能相提並論。唯一有聯絡的,就是都跟action有關。記錄下來,主要是做個備忘錄。
ASP.NET MVC 入門8、ModelState與資料驗證
ViewData有一個ModelState的屬性,這是一個型別為ModelStateDictionary的ModelState型別的字典集合。在進行資料驗證的時候這個屬性是比較有用的。在使用Html.ValidationMessage()的時候,就是從ViewData.ModelState中檢測是否有指定的K
ASP.NET MVC 入門4、Controller與Action
本系列文章基於ASP.NET MVC Preview5. Controller是MVC中比較重要的一部分。幾乎所有的業務邏輯都是在這裡進行處理的,並且從Model中取出資料。在ASP.NET MVC Preview5中,將原來的Controller類一分為二,分為了Controller類和Controller
ASP.NET MVC 入門7、Hellper與資料的提交與繫結
本系列文章基於ASP.NET MVC Preview5.
ASP.NET MVC提供了很多Hellper的方法,Hellper就是一些生成HTML程式碼的方法,方便我們書寫HTML程式碼(有一部分的朋友更喜歡直接寫HTML程式碼)。我們也可以利用.NET 3.5的擴充套件方法來書寫我們自己的Hellper。
Asp.net Mvc Preview 5 體驗--實現ActionSelectionAttribute來判斷是否為AJAX請求而選擇不同的Action
ActionSelectionAttribute是ASP.NET MVC Preview 5 提供的一個抽象基類,通過ActionSelectionAttribute的命名我們就可以猜想到這個Attribute是用來選擇(匹配)Action方法的。該抽象類只提供了一個抽象的方法 IsValidForReque
ASP.NET MVC使用UEditor,並與Controller共享
今天有人問我個小問題,我還是記錄一下吧。
在ASP.NET MVC下使用UEditor是一件很簡單的事情:
1、首先下載UEditor的JS。
2、定義一個實體類:
public class Article
{
[Key]
pu
【 .Net碼農】認識ASP.NET MVC的5種AuthorizationFilter
在總體介紹了篩選器及其提供機制(《深入探討ASP.NET MVC的篩選器》)之後,我們按照執行的先後順序對四種不同的篩選器進行單獨介紹,首先來介紹最先執行的AuthorizationFilter。從命名來看,AuthorizationFilter用於完成授權相關的工作,所以它應該在Action方法被呼叫之前執
Asp.NET MVC 使用 SignalR 實現推送功能二(Hubs 線上聊天室 獲取儲存使用者資訊)
簡單介紹
在上一篇中,我們只是介紹了簡單的訊息推送,今天我們來修改一下,實現儲存訊息,歷史訊息和使用者線上
使用者登入註冊資訊
當用戶登入之後,我們註冊一下使用者的資訊,我們在ChatHub中 新建一個方法 Register(使用者帳號,使用者密碼)
前臺js呼叫這個方法實現使用者註冊
【無私分享:從入門到精通ASP.NET MVC】從0開始,一起搭框架、做專案(5.4) 登入功能的實現,建立與登入使用者相關的介面和實現類
索引
簡述
今天我們建立幾個與登入使用者相關的資料表的介面和實現類
專案準備
我們用的工具是:VS 2013 + SqlServer 2012 + IIS7.5
希望大家對ASP.NET MVC有一個初步的理解,理論性的東西我們不做過多解釋,有些地方不理解也沒關係,會用就行了,用的多了,用的久了
ASP.NET MVC 5 Controllers and Actions
del png asp.net obj into sse ascx stat wan Creating a Controller with IController
All controller classes must implemet IController interf
ASP.NET MVC 排球計分程序 (三)需求分析與數據庫設計
arch 情況 img 需求 全場 ima 功能 每次 str 需求分析:
軟件名稱:排球計分程序
1、 需要鍵入比賽人員的的姓名,需要根據場上的比賽結果及時做出操作,記分員可以在記錯的情況下撤銷上一部操作。比賽結束,記分員應能查詢到每個隊伍的進球情況,以及攔網、擊球等的
asp.net mvc中如何處理字符串與對象之間的序列化與反序列化(一)
osi strong 類結構 plain pbo edate inf esc arp 前臺我們一般用ajax來發送數據到後端進行處理,如果json數據結構和後臺的實體類結構一致,就直接可以反序列化為指定的對象進行操作,非常方便。
前端發送的json數據結構:
後端實體結
asp.net MVC 5 路由 Routing
onf 模型 控制 ace 讓我 view 字符 blog cal ASP.NET MVC ,一個適用於WEB應用程序的經典模型 model-view-controller 模式。相對於web forms一個單一的整塊,asp.net mvc是由連接在一起的各種代碼層所組成