private static object[] GetActionCallParameters(HttpContext context, ActionDescription action) { if (action.Parameters == null || action.Parameters.Length == 0) { return(null); } IActionParametersProvider provider = ActionParametersProviderFactory.CreateActionParametersProvider(context); return(provider.GetParameters(context, action)); }
/// <summary> /// 根据要调用的方法名返回对应的 Action /// </summary> /// <param name="controller"></param> /// <param name="action"></param> /// <param name="request"></param> /// <returns></returns> private static ActionDescription GetServiceAction(Type controller, string action, HttpRequest request) { if (controller == null) { throw new ArgumentNullException("controller"); } if (string.IsNullOrEmpty(action)) { throw new ArgumentNullException("action"); } // 首先尝试从缓存中读取 string key = request.HttpMethod + "#" + controller.FullName + "@" + action; ActionDescription mi = (ActionDescription)s_ServiceActionTable[key]; if (mi == null) { bool saveToCache = true; MethodInfo method = FindAction(action, controller, request); if (method == null) { // 如果Action的名字是submit并且是POST提交,则需要自动寻找Action // 例如:多个提交都采用一样的方式:POST /Ajax/Product/submit if (action.IsSame("submit") && request.HttpMethod.IsSame("POST")) { // 自动寻找Action method = FindSubmitAction(controller, request); saveToCache = false; } } if (method == null) { return(null); } var attr = method.GetMyAttribute <ActionAttribute>(); mi = new ActionDescription(method, attr); if (saveToCache) { s_ServiceActionTable[key] = mi; } } return(mi); }
/// <summary> /// 根据一个页面请求路径,返回内部表示的调用信息。 /// </summary> /// <param name="url"></param> /// <returns></returns> public static InvokeInfo GetActionInvokeInfo(string url) { if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } MatchActionDescription md = null; ActionDescription action = null; // 先直接用URL从字典中查找匹配项。 if (s_PageActionDict.TryGetValue(url, out action) == false) { // 如果不能直接匹配URL,就用正则表达式再逐个匹配。 md = GetActionUsingRegex(url); if (md == null) { return(null); } else { action = md.ActionDescription; } } InvokeInfo vkInfo = new InvokeInfo(); vkInfo.Controller = action.PageController; vkInfo.Action = action; if (md != null) { vkInfo.RegexMatch = md.Match; } if (vkInfo.Action.MethodInfo.IsStatic == false) { //vkInfo.Instance = Activator.CreateInstance(vkInfo.Controller.ControllerType); vkInfo.Instance = vkInfo.Controller.ControllerType.FastNew(); } return(vkInfo); }
/// <summary> /// 加载所有的Controller /// </summary> private static void InitControllers() { BaseActionHandlerFactory[] baseActionHandlerFactoryList = GetConfigBaseActionHandlerFactory(); List <ControllerDescription> serviceControllerList = new List <ControllerDescription>(1024); var pageControllerList = new List <ControllerDescription>(1024); ICollection assemblies = BuildManager.GetReferencedAssemblies(); foreach (Assembly assembly in assemblies) { // 过滤以【System】开头的程序集,加快速度 if (assembly.FullName.StartsWith("System", StringComparison.OrdinalIgnoreCase)) { continue; } foreach (Type t in assembly.GetExportedTypes()) { if (t.IsClass == false) { continue; } if (t.Name.EndsWith("Controller")) { pageControllerList.Add(new ControllerDescription(t)); } for (int i = 0; i < baseActionHandlerFactoryList.Length; i++) { if (baseActionHandlerFactoryList[i].TypeIsService(t)) { serviceControllerList.Add(new ControllerDescription(t)); break; } } } } // 用于Ajax or Service 调用的Action信息则采用延迟加载的方式。 s_ServiceFullNameDict = serviceControllerList.ToDictionary(x => x.ControllerType.FullName, StringComparer.OrdinalIgnoreCase); s_ServiceShortNameDict = new Dictionary <string, ControllerDescription>(s_ServiceFullNameDict.Count, StringComparer.OrdinalIgnoreCase); foreach (ControllerDescription description in serviceControllerList) { try { s_ServiceShortNameDict.Add(description.ControllerType.Name, description); } catch (ArgumentException) { // 如果遇到已存在的KEY,把原先存放的项也设置为 null,便于查找时返回 null // 也就是说:短名不能重复,如果重复则不返回任何一个。 s_ServiceShortNameDict[description.ControllerType.Name] = null; } } // 提前加载Page Controller中的所有Action方法 s_PageActionDict = new Dictionary <string, ActionDescription>(4096, StringComparer.OrdinalIgnoreCase); List <RegexActionDescription> regexActions = new List <RegexActionDescription>(); foreach (ControllerDescription controller in pageControllerList) { foreach (MethodInfo m in controller.ControllerType.GetMethods(ActionBindingFlags)) { ActionAttribute actionAttr = m.GetMyAttribute <ActionAttribute>(); if (actionAttr != null) { ActionDescription actionDescription = new ActionDescription(m, actionAttr) { PageController = controller }; PageUrlAttribute[] pageUrlAttrs = m.GetMyAttributes <PageUrlAttribute>(); foreach (PageUrlAttribute attr in pageUrlAttrs) { if (string.IsNullOrEmpty(attr.Url) == false) { s_PageActionDict.Add(attr.Url, actionDescription); } } PageRegexUrlAttribute[] regexAttrs = m.GetMyAttributes <PageRegexUrlAttribute>(); foreach (PageUrlAttribute attr2 in regexAttrs) { if (string.IsNullOrEmpty(attr2.Url) == false) { Regex regex = new Regex(attr2.Url, RegexOptions.Compiled); regexActions.Add(new RegexActionDescription { Regex = regex, ActionDescription = actionDescription }); } } } } } if (regexActions.Count > 0) { s_RegPageActionArray = regexActions.ToArray(); } }