程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> ASP.NET MVC Preview生命周期分析(三)

ASP.NET MVC Preview生命周期分析(三)

編輯:關於ASP.NET

詳細看看InvokeAction方式的執行:

protected internal bool InvokeAction(string actionName) {
      return InvokeAction (actionName, new RouteValueDictionary());
    }
     protected internal virtual bool InvokeAction(string actionName, RouteValueDictionary values) {
      if (String.IsNullOrEmpty(actionName)) {
        throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
      }
      // We have to loop through all the methods to make sure there isn't
       // a conflict. If we stop the loop the first time we find a match
      // we might miss some error cases.
       MemberInfo[] membInfos = GetType().GetMember(actionName, MemberTypes.Method,
        BindingFlags.IgnoreCase | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
      MethodInfo foundMatch = null;
      foreach (MemberInfo memberInfo in membInfos) {
         MethodInfo mi = (MethodInfo)memberInfo;
         // 1) Action methods must not have the non-action attribute in their inheritance chain, and
        // 2) special methods like constructors, property accessors, and event accessors cannot be action methods, and
        // 3) methods originally defined on Object (like ToString) or Controller cannot be action methods.
         if (!mi.IsDefined(typeof(NonActionAttribute), true) &&
          !mi.IsSpecialName &&
          mi.DeclaringType.IsSubclassOf(typeof(Controller))) {
          if (foundMatch != null) {
             throw new InvalidOperationException(
               String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MoreThanOneAction, actionName, GetType()));
          }
          foundMatch = mi;
        }
      }
      if (foundMatch != null) {
        InvokeActionMethod(foundMatch, values);
        return true;
      }
       return false;
    }
它通過反射獲取所有同名 Action 方法信 息;其次,它過濾掉所有有 NonActionAttribute 和 IsSpecialName 標記的方法 ;第三,當同名有效 Action 被重載時它會拋出異常(提示 Controller_MoreThanOneAction),繼續調用InvokeActionMethod:

[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters",
   Justification = "We use MethodInfo since it represents only methods and not constructors." +
   "This method only makes sense for use with methods.")]
protected internal virtual void InvokeActionMethod(MethodInfo methodInfo, RouteValueDictionary values) {
   if (methodInfo == null) {
     throw new ArgumentNullException("methodInfo");
   }
   if (values == null) {
     values = new RouteValueDictionary();
   }
   if (methodInfo.ContainsGenericParameters) {
     throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_ActionCannotBeGeneric, methodInfo.Name));
   }
   ParameterInfo[] methodParameters = methodInfo.GetParameters();
   object[] parameterValues = null;
   if (methodParameters.Length > 0) {
     parameterValues = new object[methodParameters.Length];
     for (int i = 0; i < methodParameters.Length; i++) {
        ParameterInfo pi = methodParameters[i];
       if (pi.IsOut || pi.ParameterType.IsByRef) {
         throw new InvalidOperationException(String.Format (CultureInfo.CurrentUICulture, MvcResources.Controller_ReferenceParametersNotSupported, pi.Name, methodInfo.Name));
       }
       bool valueRequired = true;
       if (pi.ParameterType.IsClass) {
         // Classes (ref types) don't require values since we can pass in null
         valueRequired = false;
       }
       else {
          if ((pi.ParameterType.IsGenericType && ! pi.ParameterType.IsGenericTypeDefinition) &&
            (pi.ParameterType.GetGenericTypeDefinition() == typeof (Nullable<>))) {
           // Nullable types don't require values since we can pass in null
            valueRequired = false;
         }
       }
       // Try to get a value for the parameter. We use this order of precedence:
       // 1. Explicitly-provided extra parameters in the call to InvokeAction()
       // 2. Values from the RouteData (could be from the typed-in URL or from the route's default values)
       // 3. Request values (query string, form post data, cookie)
       object parameterValue = null;
       if (!values.TryGetValue (methodParameters[i].Name, out parameterValue)) {
         if (RouteData == null || !RouteData.Values.TryGetValue (methodParameters[i].Name, out parameterValue)) {
            if (Request != null) {
             parameterValue = Request[methodParameters[i].Name];
            }
         }
       }
       if (parameterValue == null && valueRequired) {
          throw new InvalidOperationException(String.Format (CultureInfo.CurrentUICulture, MvcResources.Controller_MissingParameter, pi.Name, methodInfo.Name));
       }
       try {
          parameterValues[i] = ConvertParameterType (parameterValue, methodParameters[i].ParameterType, methodParameters [i].Name, methodInfo.Name);
       }
       catch (Exception ex) {
         // Parameter value conversion errors are acceptable unless the value is required
          if (valueRequired) {
           throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MissingParameter, pi.Name, methodInfo.Name), ex);
         }
       }
     }
   }
   InvokeActionMethodFilters(methodInfo, () => methodInfo.Invoke(this, parameterValues));
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved