<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET MVC是如何運行的(4): Action的執行

      作為Controller基類ControllerBase的Execute方法的核心在于對Action方法的執行和作為方法返回的ActionResult的執行,兩者的執行是通過一個叫做ActionInvoker的組件來完成的。

      一、ActionInvoker

      我們同樣為ActionInvoker定義了一個接口IActionInvoker。如下面的代碼片斷所示,該接口定義了一個唯一的方法InvokeAction用于執行指定名稱的Action方法,該方法的第一個參數是一個表示基于當前Controller上下文的ControllerContext對象。

         1: public interface IActionInvoker
         2: {
         3:     void InvokeAction(ControllerContext controllerContext, string actionName);
         4: }

      ControllerContext類型在真正的ASP.NET MVC框架中要負責一些,在這里我們對它進行了簡化,僅僅將它表示成對當前Controller和請求上下文的封裝,而這兩個要素分別通過如下所示的Controller和RequestContext屬性表示。

         1: public class ControllerContext
         2: {
         3:     public ControllerBase Controller { get; set; }
         4:     public RequestContext RequestContext { get; set; }
         5: }

      ControllerBase中表示ActionInvoker的同名屬性在構造函數中被初始化。在Execute方法中,通過作為方法參數的RequestContext對象創建ControllerContext對象,并通過包含在RequestContext中的RouteData得到目標Action的名稱,然后將這兩者作為參數調用ActionInvoker的InvokeAction方法。

      從前面給出的關于ControllerBase的定義我們可以看到在構造函數中默認創建的ActionInvoker是一個類型為ControllerActionInvoker的對象。如下所示的代碼片斷反映了整個ControllerActionInvoker的定義,而InvokeAction方法的目的在于實現針對Action方法的執行。由于Action方法具有相應的參數,在執行Action方法之前必須進行參數的綁定。ASP.NET MVC將這個機制成為Model的綁定,而這又涉及到另一個重要的組件ModelBinder。

         1: public class ControllerActionInvoker : IActionInvoker
         2: {
         3:     public IModelBinder ModelBinder { get; private set; }
         4:     public ControllerActionInvoker()
         5:     {
         6:         this.ModelBinder = new DefaultModelBinder();
         7:     }
         8:     public void InvokeAction(ControllerContext controllerContext, string actionName)
         9:     {
        10:         MethodInfo method = controllerContext.Controller.GetType().GetMethods().First(m => string.Compare(actionName, m.Name, true) == 0);
        11:         List<object> parameters = new List<object>();
        12:         foreach (ParameterInfo parameter in method.GetParameters())
        13:         {
        14:             parameters.Add(this.ModelBinder.BindModel(controllerContext, parameter.Name, parameter.ParameterType));
        15:         }
        16:         ActionResult actionResult = method.Invoke(controllerContext.Controller, parameters.ToArray()) as ActionResult;
        17:         actionResult.ExecuteResult(controllerContext);
        18:     }
        19: }

      二、ModelBinder

      我們為ModelBinder提供了一個如下一個簡單的定義,這與在真正的ASP.NET MVC中的同名接口的定義不盡相同。該接口具有唯一的BindModel根據ControllerContext和Model名稱(在這里實際上是參數名稱)和類型得到一個作為參數的對象。

         1: public interface IModelBinder
         2: {
         3: object BindModel(ControllerContext controllerContext, string modelName, Type modelType);
         4: }

      通過前面給出的關于ControllerActionInvoker的定義我們可以看到在構造函數中默認創建的ModelBinder對象是一個DefaultModelBinder對象。由于僅僅是對ASP.NET MVC的模擬,定義在自定義的DefaultModelBinder中的Model綁定邏輯比ASP.NET MVC中同名類型中實現的要簡單得多。

      如下面的代碼片斷所示,綁定到參數上的數據具有三個來源:HTTP-POST Form、RouteData和Values和DataTokens,它們都是字典結構的數據集合。如果參數類型為字符串或者簡單的值類型,我們直接根據參數名稱和Key進行匹配;對于復雜類型(比如之前例子中定義的包含Contrller和Action名稱的數據類型SimpleModel),則通過反射根據類型創建新的對象并根據屬性名稱與Key的匹配關系對相應的屬性進行賦值。

         1: public class DefaultModelBinder : IModelBinder
         2: {
         3:     public object BindModel(ControllerContext controllerContext, string modelName, Type modelType)
         4:     {
         5:         if (modelType.IsValueType || typeof(string) == modelType)
         6:         {
         7:             object instance;
         8:             if (GetValueTypeInstance(controllerContext, modelName, modelType, out instance))
         9:             {
        10:                 return instance;
        11:             };
        12:             return Activator.CreateInstance(modelType);
        13:         }
        14:         object modelInstance = Activator.CreateInstance(modelType);
        15:         foreach (PropertyInfo property in modelType.GetProperties())
        16:         {
        17:             if (!property.CanWrite || (!property.PropertyType.IsValueType && property.PropertyType!= typeof(string)))
        18:             {
        19:                 continue;
        20:             }
        21:             object propertyValue;
        22:             if (GetValueTypeInstance(controllerContext, property.Name, property.PropertyType, out propertyValue))
        23:             {
        24:                 property.SetValue(modelInstance, propertyValue, null);
        25:             }
        26:         }
        27:         return modelInstance;
        28:     }
        29:     private  bool GetValueTypeInstance(ControllerContext controllerContext, string modelName, Type modelType, out object value)
        30:     {
        31:         var form = HttpContext.Current.Request.Form;
        32:         string key;
        33:         if (null != form)
        34:         {
        35:             key = form.AllKeys.FirstOrDefault(k => string.Compare(k, modelName, true) == 0);
        36:             if (key != null)
        37:             {
        38:                 value =  Convert.ChangeType(form[key], modelType);
        39:                 return true;
        40:             }
        41:         }
        42:  
        43:         key = controllerContext.RequestContext.RouteData.Values
        44:             .Where(item => string.Compare(item.Key, modelName, true) == 0)
        45:             .Select(item => item.Key).FirstOrDefault();
        46:         if (null != key)
        47:         {
        48:             value = Convert.ChangeType(controllerContext.RequestContext.RouteData.Values[key], modelType);
        49:             return true;
        50:         }
        51:  
        52:         key = controllerContext.RequestContext.RouteData.DataTokens
        53:             .Where(item => string.Compare(item.Key, modelName, true) == 0)
        54:             .Select(item => item.Key).FirstOrDefault();
        55:         if (null != key)
        56:         {
        57:             value = Convert.ChangeType(controllerContext.RequestContext.RouteData.DataTokens[key], modelType);
        58:             return true;
        59:         }
        60:         value = null;
        61:         return false;
        62:     }
        63: }

      在ControllerActionInvoker的InvokeAction方法中,我們直接將傳入的Action名稱作為方法名從Controller類型中得到表示Action操作的MethodInfo對象。然后遍歷MethodInfo的參數列表,對于每一個ParameterInfo對象,我們將它的Name和ParameterType屬性表示的參數名稱和類型連同創建ControllerContext作為參數調用ModelBinder的BindModel方法并得到對應的參數值。最后通過反射的方式傳入參數列表并執行MethodInfo。和真正的ASP.NET MVC一樣,定義在Contrller的Action方法返回一個ActionResult對象,我們通過指定它的Execute方法是先對請求的響應。

      三、ActionResult

      我們為具體的ActionResult定義了一個ActionResult抽象基類。如下面的代碼片斷所示,該抽象類具有一個參數類型為ControllerContext的抽象方法ExecuteResult,我們最終對請求的響應就實現在這里。

         1: public abstract class ActionResult
         2: {        
         3:     public abstract void ExecuteResult(ControllerContext context);
         4: }

      在之前創建的例子中,Action方法返回的是一個類型為RawContentResult的對象。顧名思義,RawContentResult將初始化時指定的內容(字符串)原封不動地寫入針對當前請求的HTTP回復中,具體的實現如下所示。

         1: public class RawContentResult: ActionResult
         2: {
         3:     public string RawData { get; private set; }
         4:     public RawContentResult(string rawData)
         5:     {
         6:         RawData = rawData; 
         7:     }
         8:     public override void ExecuteResult(ControllerContext context)
         9:     {
        10:         context.RequestContext.HttpContext.Response.Write(this.RawData);
        11:     }
        12: }

       

      ASP.NET MVC是如何運行的[1]: 建立在“偽”MVC框架上的Web應用
      ASP.NET MVC是如何運行的[2]: URL路由
      ASP.NET MVC是如何運行的[3]: Controller的激活
      ASP.NET MVC是如何運行的[4]: Action的執行

      posted @ 2012-03-12 17:30  Artech  閱讀(16451)  評論(27)    收藏  舉報
      主站蜘蛛池模板: 少妇伦子伦情品无吗| 洪江市| 亚洲综合区激情国产精品| 激情在线一区二区三区视频| 日韩丝袜亚洲国产欧美一区| 中文字幕人妻丝袜美腿乱| 熟女精品色一区二区三区| 国产无套粉嫩白浆在线| 伊人成色综合人夜夜久久| 99精品热在线在线观看视| 七台河市| 亚洲欧美人成人让影院| 国产成人久久综合一区| 龙门县| 天干天干夜啦天干天干国产| 亚洲精品国产福利一区二区| 免费的特黄特色大片| 日韩人妖精品一区二区av| 久久综合色之久久综合| 国产午夜福利精品视频| 久久天天躁狠狠躁夜夜avapp | 美女自卫慰黄网站| 亚洲精品理论电影在线观看 | 西青区| 日本伊人色综合网| 成人无码午夜在线观看| 色爱综合另类图片av| 亚洲成人av高清在线| 国内精品自线在拍| 色爱无码av综合区| 亚洲精品精华液一区二区| 亚洲欧美日韩综合久久久| 阿克陶县| 99久热在线精品视频| 精品一区二区成人精品| 国内不卡不区二区三区| 四虎网址| 99精品伊人久久久大香线蕉| 国产一区二区三区禁18| 免费日韩av网在线观看| 国产精品爽爽v在线观看无码|