コード例 #1
0
        public static void Run1 <TContext, TRequest>(TContext context, NFinal.Action.ActionData <TContext, TRequest> actionData, TRequest request, NameValueCollection parameters)
        {
            using (Index controller = new Index())
            {
                Request request1 = null;
                IDictionary <string, object> context1 = null;
                //初始化

                controller.Initialization(context1, "Index", null, request1, CompressMode.None);
                ViewModel ViewBag = new ViewModel();
                ViewBag.a = 2;
                ViewBag.b = "3";

                ViewBag.c          = Index.c;
                ViewBag.c1         = Index.c1;
                controller.ViewBag = ViewBag;
                if (!controller.Before())
                {
                    return;
                }
                if (!Filter.FilterHelper.AuthorizationFilter(actionData.IAuthorizationFilters, controller))
                {
                    return;
                }
                if (!Filter.FilterHelper.BeforeActionFilter(actionData.IBeforeActionFilters, controller))
                {
                    return;
                }
                //添参数问题。。。
                //string a = request.parameters["a"];
                //int b = request.parameters["b"];
                //int? b1 = request.parameters["b1"];
                //ParameterModel c = new ParameterModel();
                //c = NFinal.Model.ModelHelper.GetModel(new ParameterModel(), request.parameters);
                controller.Index1(parameters["a"], parameters["b"], NFinal.Model.ModelHelper.GetModel <ParameterModel>(parameters));
                controller.After();
                if (!Filter.FilterHelper.AfterActionFilter(actionData.IAfterActionFilters, controller))
                {
                    return;
                }
                Filter.FilterHelper.AfterActionFilter(actionData.IAfterActionFilters, controller);
                if (!NFinal.Filter.FilterHelper.ResponseFilter(actionData.IResponseFilters, controller.response))
                {
                    return;
                }
                controller.Close();
            }
        }
コード例 #2
0
        /// <summary>
        /// 获取执行控制器行为的代理函数
        /// </summary>
        /// <typeparam name="TContext">Http上下文信息类型</typeparam>
        /// <typeparam name="TRequest">Http请求信息类型</typeparam>
        /// <param name="assembly">程序集</param>
        /// <param name="controllerType">控制器类型</param>
        /// <param name="actionMethodInfo">控制器行为对应方法的反射信息</param>
        /// <returns></returns>
        public static ActionExecute <TContext, TRequest> GetRunActionDelegate <TContext, TRequest>(Assembly assembly, Type controllerType, System.Reflection.MethodInfo actionMethodInfo, ActionData <TContext, TRequest> actionData)
        {
            var TContextType = typeof(TContext);

            if (StringContainerOpImplicitMethodInfoDic == null)
            {
                StringContainerOpImplicitMethodInfoDic = new Dictionary <RuntimeTypeHandle, System.Reflection.MethodInfo>();
                System.Reflection.MethodInfo[] methodInfos = typeof(StringContainer).GetMethods();
                foreach (var methodInfo in methodInfos)
                {
                    if (methodInfo.Name == "op_Implicit" && methodInfo.ReturnType != typeof(StringContainer))
                    {
                        StringContainerOpImplicitMethodInfoDic.Add(methodInfo.ReturnType.TypeHandle, methodInfo);
                    }
                }
            }
            DynamicMethod method     = new DynamicMethod("RunActionX", typeof(void), new Type[] { typeof(TContext), typeof(NFinal.Action.ActionData <TContext, TRequest>), typeof(TRequest), typeof(NameValueCollection) });
            ILGenerator   methodIL   = method.GetILGenerator();
            var           methodEnd  = methodIL.DefineLabel();
            var           request    = methodIL.DeclareLocal(typeof(TRequest));
            var           controller = methodIL.DeclareLocal(controllerType);

            var defaultConstructor = controllerType.GetConstructor(Type.EmptyTypes);

            methodIL.Emit(OpCodes.Newobj, defaultConstructor);
            methodIL.Emit(OpCodes.Stloc, controller);

            //0.context,1.actionData,2.request,3.parameters
            //try
            methodIL.BeginExceptionBlock();
            {
                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //controller,environment
                methodIL.Emit(OpCodes.Ldarg_0);
                //controller,environment,"methodName"
                methodIL.Emit(OpCodes.Ldstr, actionMethodInfo.Name);
                //controller,environment,"methodName",null
                methodIL.Emit(OpCodes.Ldnull);
                //controller,environment,"methodName",null,Request
                methodIL.Emit(OpCodes.Ldarg_2);
                //controller,environment,"methodName",null,Request,CompressMode
                methodIL.Emit(OpCodes.Ldc_I4, (int)CompressMode.Deflate);
                //controller,environment,"methodName",null,Request,CompressMode,actionData
                methodIL.Emit(OpCodes.Ldarg_1);
                //controller,environment,"methodName",null,Request,CompressMode,actionData.plugConfig
                methodIL.Emit(OpCodes.Ldfld, typeof(NFinal.Action.ActionData <TContext, TRequest>).GetField("plugConfig"));
                methodIL.Emit(OpCodes.Callvirt, controllerType.GetMethod("Initialization",
                                                                         new Type[] { typeof(TContext),
                                                                                      typeof(string),
                                                                                      typeof(System.IO.Stream),
                                                                                      typeof(TRequest),
                                                                                      typeof(CompressMode),
                                                                                      typeof(NFinal.Config.Plug.PlugConfig) }));
                #region 执行用户权限过滤器
                //actionData
                methodIL.Emit(OpCodes.Ldarg_1);
                //actionData.IAuthorizationFilters//泛型的类型必须固定
                methodIL.Emit(OpCodes.Ldfld, typeof(NFinal.Action.ActionData <TContext, TRequest>).GetField("IAuthorizationFilters"));
                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);//泛型的类型必须固定
                methodIL.Emit(OpCodes.Call, AuthorizationFilterMethodInfo.MakeGenericMethod(new Type[] { typeof(TContext), typeof(TRequest) }));
                var BeforeAuthorizationEnd = methodIL.DefineLabel();
                methodIL.Emit(OpCodes.Brtrue_S, BeforeAuthorizationEnd);
                methodIL.Emit(OpCodes.Leave, methodEnd);//离函数体较远,使用leave_s会报错。
                methodIL.MarkLabel(BeforeAuthorizationEnd);
                #endregion

                #region 执行Action执行之前的过滤器
                //actionData
                methodIL.Emit(OpCodes.Ldarg_1);
                //actionData.IBeforeActionFilters
                methodIL.Emit(OpCodes.Ldfld, typeof(NFinal.Action.ActionData <TContext, TRequest>).GetField("IBeforeActionFilters"));
                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //FilterHelper.BeforeActionFilter();
                methodIL.Emit(OpCodes.Call, BeforeActionFilterMethodInfo.MakeGenericMethod(new Type[] { typeof(TContext), typeof(TRequest) }));
                var BeforeActionEnd = methodIL.DefineLabel();
                methodIL.Emit(OpCodes.Brtrue_S, BeforeActionEnd);
                methodIL.Emit(OpCodes.Leave, methodEnd);
                methodIL.MarkLabel(BeforeActionEnd);
                #endregion

                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //controller.Before();
                methodIL.Emit(OpCodes.Callvirt, controllerType.GetMethod("Before", Type.EmptyTypes));
                //bool,0
                var BeforeEnd = methodIL.DefineLabel();
                methodIL.Emit(OpCodes.Brtrue_S, BeforeEnd);
                methodIL.Emit(OpCodes.Leave, methodEnd);
                methodIL.MarkLabel(BeforeEnd);

                //ViewBag初始化
                if (true)
                {
                    var  ControllerViewBagFieldInfo = controllerType.GetField("ViewBag");
                    Type ViewBagType = Type.GetTypeFromHandle(actionData.viewBagType);
                    //if (ControllerViewBagFieldInfo.FieldType == typeof(object))
                    //{
                    //    string modelTypeName = controllerType.Namespace + "." + controllerType.Name + "_Model";
                    //    modelTypeName += "." + actionMethodInfo.Name;
                    //    ViewBagType = assembly.GetType(modelTypeName);
                    //    if (ViewBagType == null)
                    //    {
                    //        throw new NFinal.Exceptions.ModelNotFoundException(modelTypeName);
                    //    }
                    //}
                    //else
                    //{
                    //    ViewBagType = ControllerViewBagFieldInfo.FieldType;
                    //}
                    var  ViewBagContructorInfo = ViewBagType.GetConstructor(Type.EmptyTypes);
                    var  ViewBag = methodIL.DeclareLocal(ViewBagType);
                    bool viewBagTypeIsExpandoObject = false;
                    if (ViewBagType == typeof(System.Dynamic.ExpandoObject))
                    {
                        viewBagTypeIsExpandoObject = true;
                    }
                    //controller
                    methodIL.Emit(OpCodes.Newobj, ViewBagContructorInfo);
                    methodIL.Emit(OpCodes.Stloc, ViewBag);
                    List <FieldInfo> viewBagFiledInfoList    = new List <FieldInfo>();
                    List <FieldInfo> controllerFieldInfoList = new List <FieldInfo>();
                    //获取所有字段
                    var controllerFieldInfos = controllerType.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy);
                    foreach (var controllerFieldInfo in controllerFieldInfos)
                    {
                        //查找Controller中具有ViewBagMember特性的字段
                        var viewBagMemberAttribute = controllerFieldInfo.GetCustomAttributes(typeof(ViewBagMemberAttribute), true);
                        if (viewBagMemberAttribute.Count() > 0)
                        {
                            if (viewBagTypeIsExpandoObject)
                            {
                                controllerFieldInfoList.Add(controllerFieldInfo);
                            }
                            else
                            {
                                var ViewBagFiledInfo = ViewBagType.GetField(
                                    controllerFieldInfo.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                                //查找到ViewBag中具有相同名字的字段
                                if (ViewBagFiledInfo != null && ViewBagFiledInfo.FieldType == controllerFieldInfo.FieldType)
                                {
                                    viewBagFiledInfoList.Add(ViewBagFiledInfo);
                                    controllerFieldInfoList.Add(controllerFieldInfo);
                                }
                            }
                        }
                    }

                    List <MethodInfo> controllerProperyInfoGetMethodList = new List <MethodInfo>();
                    List <MethodInfo> viewBagPropertyInfoSetMethodList   = new List <MethodInfo>();
                    var controllerPropertyInfos = controllerType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy);
                    foreach (var controllerPropertyInfo in controllerPropertyInfos)
                    {
                        var viewBagMemberAttribute = controllerPropertyInfo.GetCustomAttributes(typeof(ViewBagMemberAttribute), true);
                        if (viewBagMemberAttribute.Count() > 0)
                        {
                            if (viewBagTypeIsExpandoObject)
                            {
                                controllerProperyInfoGetMethodList.Add(controllerPropertyInfo.GetGetMethod());
                            }
                            else
                            {
                                var viewBagPropertyInfo = ViewBagType.GetProperty(
                                    controllerPropertyInfo.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
                                if (viewBagPropertyInfo != null && viewBagPropertyInfo.PropertyType == controllerPropertyInfo.PropertyType)
                                {
                                    MethodInfo controllerPropertyInfoGetMethod = controllerPropertyInfo.GetGetMethod();
                                    MethodInfo viewBagPropertyInfoSetMethod    = viewBagPropertyInfo.GetSetMethod();
                                    controllerProperyInfoGetMethodList.Add(controllerPropertyInfoGetMethod);
                                    viewBagPropertyInfoSetMethodList.Add(viewBagPropertyInfoSetMethod);
                                }
                            }
                        }
                    }
                    Type viewBagOperateStaticType = null;
                    if (viewBagTypeIsExpandoObject)
                    {
                    }
                    for (int i = 0; i < viewBagFiledInfoList.Count; i++)
                    {
                        FieldInfo controllerFieldInfo = controllerFieldInfoList[i];
                        FieldInfo viewBagFiledInfo    = viewBagFiledInfoList[i];
                        if (controllerFieldInfo.IsStatic)
                        {
                            methodIL.Emit(OpCodes.Ldloc, ViewBag);
                            methodIL.Emit(OpCodes.Ldsfld, controllerFieldInfo);
                            methodIL.Emit(OpCodes.Stfld, viewBagFiledInfo);
                        }
                        else
                        {
                            //赋值操作
                            methodIL.Emit(OpCodes.Ldloc, ViewBag);
                            methodIL.Emit(OpCodes.Ldloc, controller);
                            methodIL.Emit(OpCodes.Ldfld, controllerFieldInfo);
                            methodIL.Emit(OpCodes.Stfld, viewBagFiledInfo);
                        }
                    }
                    for (int i = 0; i < viewBagPropertyInfoSetMethodList.Count; i++)
                    {
                        MethodInfo controllerPropertyInfoGetMethod = controllerProperyInfoGetMethodList[i];
                        MethodInfo viewBagPropertyInfoSetMethod    = viewBagPropertyInfoSetMethodList[i];
                        if (controllerPropertyInfoGetMethod.IsStatic)
                        {
                            methodIL.Emit(OpCodes.Ldloc, ViewBag);
                            methodIL.Emit(OpCodes.Call, controllerPropertyInfoGetMethod);
                            methodIL.Emit(OpCodes.Callvirt, viewBagPropertyInfoSetMethod);
                        }
                        else
                        {
                            methodIL.Emit(OpCodes.Ldloc, ViewBag);
                            methodIL.Emit(OpCodes.Ldloc, controller);
                            methodIL.Emit(OpCodes.Callvirt, controllerPropertyInfoGetMethod);
                            methodIL.Emit(OpCodes.Callvirt, viewBagPropertyInfoSetMethod);
                        }
                    }
                    methodIL.Emit(OpCodes.Ldloc, controller);
                    methodIL.Emit(OpCodes.Ldloc, ViewBag);
                    methodIL.Emit(OpCodes.Stfld, ControllerViewBagFieldInfo);
                }

                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                System.Reflection.ParameterInfo[] parameterInfos = actionMethodInfo.GetParameters();
                //添加参数
                if (parameterInfos.Length > 0)
                {
                    for (int i = 0; i < parameterInfos.Length; i++)
                    {
                        Type parameterType = parameterInfos[i].ParameterType;
                        if (parameterInfos[i].ParameterType
#if (NET40 || NET451 || NET461)
                            .IsGenericType
#endif
#if NETCORE
                            .GetTypeInfo().IsGenericType
#endif
                            && parameterInfos[i].ParameterType.GetGenericTypeDefinition() == typeof(Nullable <>))
                        {
                            parameterType = parameterInfos[i].ParameterType.GetGenericArguments()[0];
                        }
                        if (parameterType == typeof(System.String) ||
                            parameterType == typeof(System.Int32) ||
                            parameterType == typeof(System.Int16) ||
                            parameterType == typeof(System.Int64) ||
                            parameterType == typeof(System.UInt32) ||
                            parameterType == typeof(System.UInt16) ||
                            parameterType == typeof(System.UInt64) ||
                            parameterType == typeof(System.Byte) ||
                            parameterType == typeof(System.SByte) ||
                            parameterType == typeof(System.Single) ||
                            parameterType == typeof(System.Double) ||
                            parameterType == typeof(System.Decimal) ||
                            parameterType == typeof(System.DateTime) ||
                            parameterType == typeof(System.DateTimeOffset) ||
                            parameterType == typeof(System.Char) ||
                            parameterType == typeof(System.Boolean) ||
                            parameterType == typeof(System.Guid))
                        {
                            //parameters
                            methodIL.Emit(OpCodes.Ldarg_3);
                            //parameters,name
                            methodIL.Emit(OpCodes.Ldstr, parameterInfos[i].Name);
                            //parameters[name]
                            methodIL.Emit(OpCodes.Callvirt, nameValueCollectionGetItemMethodInfo);
                            //ParameterType op_Implicit(request.parameters[name]);隐式转换
                            methodIL.Emit(OpCodes.Call, StringContainerOpImplicitMethodInfoDic[parameterInfos[i].ParameterType.TypeHandle]);
                        }
                        else
                        {
                            //new ParameterModel();
                            //methodIL.Emit(OpCodes.Newobj, parameterInfos[i].ParameterType.GetConstructor(Type.EmptyTypes));
                            //parameters
                            methodIL.Emit(OpCodes.Ldarg_3);
                            //ModelHelper.GetModel(new ParameterModel(),parameters);
                            methodIL.Emit(OpCodes.Call, modelHelperGetModelMethodInfo.MakeGenericMethod(parameterType));
                        }
                    }
                }
                //controller.Action(par1,par2,par3.....);
                methodIL.Emit(OpCodes.Callvirt, actionMethodInfo);

                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //controller.After();
                methodIL.Emit(OpCodes.Callvirt, controllerType.GetMethod("After", Type.EmptyTypes));

                #region 执行Action执行之后的过滤器
                //actionData
                methodIL.Emit(OpCodes.Ldarg_1);
                //actionData.IBeforeActionFilters
                methodIL.Emit(OpCodes.Ldfld, typeof(NFinal.Action.ActionData <TContext, TRequest>).GetField("IAfterActionFilters"));
                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //FilterHelper.BeforeActionFilter();
                methodIL.Emit(OpCodes.Call, AfterActionFilterMethodInfo.MakeGenericMethod(new Type[] { typeof(TContext), typeof(TRequest) }));
                var AfterActionEnd = methodIL.DefineLabel();
                methodIL.Emit(OpCodes.Brtrue_S, AfterActionEnd);
                methodIL.Emit(OpCodes.Leave, methodEnd);
                methodIL.MarkLabel(AfterActionEnd);
                #endregion

                //actionData
                methodIL.Emit(OpCodes.Ldarg_1);
                //actionData.IResponseFilters
                methodIL.Emit(OpCodes.Ldfld, typeof(NFinal.Action.ActionData <TContext, TRequest>).GetField("IResponseFilters"));
                //actionData.IResponseFilters,controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //actionData.IResponseFilters,controller.response
                methodIL.Emit(OpCodes.Callvirt, controllerType.GetProperty("response").GetGetMethod());
                //FilterHelper.Filter(actionData.IResponseFilters,controller.response)
                methodIL.Emit(OpCodes.Call, ResponseFiltersMethodInfo);
                var ifResponseFiltersEnd = methodIL.DefineLabel();
                methodIL.Emit(OpCodes.Brtrue_S, ifResponseFiltersEnd);
                methodIL.Emit(OpCodes.Leave, methodEnd);
                methodIL.MarkLabel(ifResponseFiltersEnd);

                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //controller.Close();
                methodIL.Emit(OpCodes.Callvirt, controllerType.GetMethod("Close"));
                //跳出异常
                methodIL.Emit(OpCodes.Leave, methodEnd);
            }
            if (!Config.Configration.globalConfig.debug.enable)
            {
                methodIL.BeginCatchBlock(typeof(System.Exception));
                {
                    methodIL.Emit(OpCodes.Throw);
                }
            }
            //finally
            methodIL.BeginFinallyBlock();
            {
                var finallyEnd = methodIL.DefineLabel();
                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //controller==null
                methodIL.Emit(OpCodes.Brfalse_S, finallyEnd);
                //controller
                methodIL.Emit(OpCodes.Ldloc, controller);
                //controller.Dispose();
                methodIL.Emit(OpCodes.Callvirt, controllerType.GetMethod("Dispose", Type.EmptyTypes));
                //methodIL.Emit(OpCodes.Callvirt,typeof(System.IDisposable).GetMethod("Dispose",Type.EmptyTypes));
                methodIL.MarkLabel(finallyEnd);
            }
            //end
            methodIL.EndExceptionBlock();

            methodIL.MarkLabel(methodEnd);
            methodIL.Emit(OpCodes.Ret);
            ActionExecute <TContext, TRequest> getRunActionDelegate = (ActionExecute <TContext, TRequest>)method.CreateDelegate(typeof(ActionExecute <TContext, TRequest>));
            return(getRunActionDelegate);
        }
コード例 #3
0
 public static void AddActionDataForMethod<TContext, TRequest>(NFinal.Collections.FastDictionary<string, ActionData<TContext, TRequest>> actionDataDictionary,
     Dictionary<string, NFinal.Url.FormatData> formatMethodDictionary,
     Assembly assembly, Type controller,
     ActionData<TContext, TRequest> actionData,
     MethodInfo methodInfo,string controllerName,string areaName,
     NFinal.Config.Global.GlobalConfig globalConfig,
     NFinal.Plugs.PlugInfo plugInfo)
 {
     if (methodInfo.IsAbstract || methodInfo.IsVirtual || methodInfo.IsGenericMethod || methodInfo.IsPrivate||methodInfo.ReturnType!=typeof(void)
                 || methodInfo.IsStatic || methodInfo.IsConstructor)
     {
         return;
     }
     string actionName;
     string actionUrl;
     string[] actionKeys;
     string[] method;
     UrlAttribute urlAttribute;
     NFinal.Url.ActionUrlData actionUrlData;
     actionKeys = GetActionKeys(controllerName, areaName, out actionUrl, out actionName, out method,
         out urlAttribute, out actionUrlData,
         methodInfo, globalConfig, plugInfo);
     
     if (urlAttribute == null)
     {
         actionData.urlString = null;
         actionData.contentType = "text/html; charset=utf-8";
         actionData.compressMode = CompressMode.None;
     }
     else
     {
         actionData.urlString = urlAttribute.urlString;
         actionData.contentType = urlAttribute.contentType;
         actionData.compressMode = urlAttribute.compressMode;
     }
     actionData.className = controller.FullName;
     actionData.methodName = methodInfo.Name;
     actionData.actionUrlData = actionUrlData;
     actionData.controllerName = controllerName;
     actionData.areaName = areaName;
     actionData.actionUrl = actionUrl;
     actionData.actionName = actionName;
     actionData.method = method;
     actionData.plugConfig = plugInfo.config;
     if (actionData.actionUrlData != null)
     {
         formatMethodDictionary.Add(methodInfo.Name, new NFinal.Url.FormatData(actionData.actionUrlData.formatUrl, actionData.actionUrlData.actionUrlNames));
     }
     else
     {
         formatMethodDictionary.Add(methodInfo.Name, new NFinal.Url.FormatData(actionData.actionUrl, null));
     }
     actionData.IAuthorizationFilters = GetFilters<NFinal.Filter.IAuthorizationFilter>(
         typeof(NFinal.Filter.IAuthorizationFilter), controller, methodInfo);
     actionData.IParametersFilters = GetFilters<NFinal.Filter.IParameterFilter>(
         typeof(NFinal.Filter.IParameterFilter), controller, methodInfo);
     actionData.IBeforeActionFilters = GetFilters<NFinal.Filter.IBeforeActionFilter>(
         typeof(NFinal.Filter.IBeforeActionFilter), controller, methodInfo
         );
     actionData.IAfterActionFilters = GetFilters<NFinal.Filter.IAfterActionFilter>(
         typeof(NFinal.Filter.IAfterActionFilter), controller, methodInfo
         );
     actionData.IResponseFilters = GetFilters<NFinal.Filter.IResponseFilter>(
         typeof(NFinal.Filter.IResponseFilter), controller, methodInfo);
     actionData.actionExecute = NFinal.Action.Actuator.GetRunActionDelegate<TContext, TRequest>(assembly, controller, methodInfo,actionData);
     foreach (var actionKey in actionKeys)
     {
         if (actionDataDictionary.ContainsKey(actionKey))
         {
             var oldActionData = actionDataDictionary[actionKey];
             throw new NFinal.Exceptions.DuplicateActionUrlException(oldActionData.className, oldActionData.methodName, actionData.className, actionData.methodName);
         }
         else
         {
             actionDataDictionary.Add(actionKey, actionData);
         }
     }
 }
コード例 #4
0
        /// <summary>
        /// 向全局添加控制器行为信息
        /// </summary>
        /// <typeparam name="TContext">Http请求上下文类型</typeparam>
        /// <typeparam name="TRequest">Http请求类型</typeparam>
        /// <param name="actionDataDictionary">控制器行为数据信息字典</param>
        /// <param name="formatMethodDictionary">控制器行为URl格式化字典</param>
        /// <param name="assembly">当前程序集</param>
        /// <param name="controller">控制器类型信息</param>
        /// <param name="globalConfig">全局配置信息</param>
        /// <param name="plugInfo">插件信息</param>
        public static void AddActionData<TContext, TRequest>(NFinal.Collections.FastDictionary<string, ActionData<TContext, TRequest>> actionDataDictionary,
            Dictionary<string, NFinal.Url.FormatData> formatMethodDictionary,
            Assembly assembly, Type controller,
            NFinal.Config.Global.GlobalConfig globalConfig,
            NFinal.Plugs.PlugInfo plugInfo)
        {
            Type viewBagType = null;
            viewBagType = controller.GetField("ViewBag").FieldType;
            if (viewBagType == typeof(object))
            {
                MethodInfo[] actions = null;
                string controllerName;
                string areaName;

                ActionData<TContext, TRequest> actionData;
                GetControllerUrl(out controllerName, out areaName, controller, globalConfig);
                actions = controller.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
#if NETCORE
                //查找函数
                var controllerAttributeList = controller.GetTypeInfo().GetCustomAttributes(typeof(NFinal.ActionExportAttribute), true);
#else
                var controllerAttributeList = controller.GetCustomAttributes(typeof(NFinal.ActionExportAttribute), true);
#endif
                MethodInfo action = null;
                bool hasAction = false;
                ActionExportAttribute actionExportAttribute = null;
                foreach (var controllerAttribute in controllerAttributeList)
                {
                    actionExportAttribute = (NFinal.ActionExportAttribute)controllerAttribute;
                    if (actionExportAttribute.types == null)
                    {
                        action = controller.GetMethod(actionExportAttribute.methodName);
                    }
                    else
                    {
                        action = controller.GetMethod(actionExportAttribute.methodName, actionExportAttribute.types);
                    }
                    if (action == null)
                    {
                        throw new NFinal.Exceptions.NotFoundExportActionException(controller.FullName, actionExportAttribute.methodName);
                    }
                    hasAction = false;
                    foreach (var actionTmp in actions)
                    {
                        if (actionTmp == action)
                        {
                            hasAction = true;
                        }
                    }
                    if (!hasAction)
                    {
                        actionData = new ActionData<TContext, TRequest>();
                        actionData.viewBagType = actionExportAttribute.viewBagType.TypeHandle;
                        AddActionDataForMethod(actionDataDictionary, formatMethodDictionary, 
                            assembly, controller, 
                            actionData, action, 
                            controllerName, areaName, 
                            globalConfig, plugInfo);
                    }
                }

                //MethodInfo actionExportList =
                for (int m = 0; m < actions.Length; m++)
                {
                    if (actions[m].IsAbstract || actions[m].IsVirtual || actions[m].IsGenericMethod || actions[m].IsPrivate || actions[m].ReturnType != typeof(void)
                        || actions[m].IsStatic || actions[m].IsConstructor)
                    {
                        continue;
                    }
                    actionData = new ActionData<TContext, TRequest>();
                    string modelTypeName = controller.Namespace + "." + controller.Name + "_Model";
                    modelTypeName += "." + actions[m].Name;
                    viewBagType = assembly.GetType(modelTypeName);
                    if (viewBagType == null)
                    {
                        throw new NFinal.Exceptions.ModelNotFoundException(modelTypeName);
                    }
                    else
                    {
                        actionData.viewBagType = viewBagType.TypeHandle;
                    }
                    AddActionDataForMethod(actionDataDictionary, formatMethodDictionary,
                        assembly, controller,
                        actionData, actions[m],
                        controllerName, areaName,
                        globalConfig, plugInfo);
                }
            }
        }