public object[] GetParameters(HttpContext context, ActionDescription action) { if( action.Parameters.Length == 1 ) { object value = GetObjectFromRequest(context.Request, action); return new object[1] { value }; } else return GetMultiObjectsFormRequest(context.Request, action); }
/// <summary> /// 根据一个页面请求路径,返回内部表示的调用信息。 /// </summary> /// <param name="url"></param> /// <returns></returns> public InvokeInfo GetActionInvokeInfo(string url) { if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } MatchActionDescription md = null; ActionDescription action = null; // 先直接用URL从字典中查找匹配项。 if (s_metadata.PageActionDict.TryGetValue(url, out action) == false) { // 如果不能直接匹配URL,就用正则表达式再逐个匹配。 md = GetActionByRegex(url); if (md == null) { if (this.DiagnoseResult != null) { // 填充诊断结果 SetPageUrlDiagnoseResult(url); } 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.New(); } return(vkInfo); }
private object GetObjectFromRequest(HttpRequest request, ActionDescription action) { if( action.Parameters[0].ParameterType == typeof(string) ) return request.ReadInputStream(); if( action.Parameters[0].ParameterType == typeof(XmlDocument) ) { string xml = request.ReadInputStream(); XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); return doc; } Type destType = action.Parameters[0].ParameterType.GetRealType(); XmlSerializer mySerializer = new XmlSerializer(destType); request.InputStream.Position = 0; StreamReader sr = new StreamReader(request.InputStream, request.ContentEncoding); return mySerializer.Deserialize(sr); }
private object[] GetMultiObjectsFormRequest(HttpRequest request, ActionDescription action) { string xml = request.ReadInputStream(); XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); XmlNode root = doc.LastChild; //if( root.ChildNodes.Count != action.Parameters.Length ) // throw new ArgumentException("客户端提交的数据项与服务端的参数项的数量不匹配。"); object[] parameters = new object[action.Parameters.Length]; for( int i = 0; i < parameters.Length; i++ ) { string name = action.Parameters[i].Name; XmlNode node = (from n in root.ChildNodes.Cast<XmlNode>() where string.Compare(n.Name, name, StringComparison.OrdinalIgnoreCase) == 0 select n).FirstOrDefault(); try { if( node != null ) { object parameter = null; Type destType = action.Parameters[i].ParameterType.GetRealType(); if( destType.IsSupportableType() ) parameter = ModelHelper.UnSafeChangeType(node.InnerText, destType); else parameter = XmlDeserialize(node.OuterXml, destType, request.ContentEncoding); parameters[i] = parameter; } } catch( Exception ex ) { throw new InvalidCastException("数据转换失败,当前参数名:" + name, ex); } } return parameters; }
private void BuildPageActionDict(List <ControllerDescription> pageControllerList) { // 由于 PageController 中的 Action 是采用URL匹配模式(不是采用 namespace / class / method 的解析模式), // 所以需要提前加载 PageController 中的所有Action方法 // 判断逻辑: // 1、方法是公开的 // 2、有 [PageUrl] 或者 [PageRegexUrl] // 3、[Action] 是可选的,因为上面二个Attribute已经很明确了,没有它们指定URL,有[Action]也没什么用 PageActionDict = new Dictionary <string, ActionDescription>(4096, StringComparer.OrdinalIgnoreCase); List <RegexActionDescription> regexActions = new List <RegexActionDescription>(); // 遍历所有 PageController 的所有公开方法 foreach (ControllerDescription controller in pageControllerList) { foreach (MethodInfo m in controller.ControllerType.GetMethods(ActionFindBindingFlags)) { ActionDescription actionDescription = null; // 提取 PageUrlAttribute PageUrlAttribute[] pageUrlAttrs = m.GetMyAttributes <PageUrlAttribute>(); foreach (PageUrlAttribute attr in pageUrlAttrs) { if (string.IsNullOrEmpty(attr.Url) == false) { if (actionDescription == null) { actionDescription = CreatePageActionDescription(controller, m); } PageActionDict.Add(attr.Url, actionDescription); } } // 提取 PageRegexUrlAttribute PageRegexUrlAttribute[] regexAttrs = m.GetMyAttributes <PageRegexUrlAttribute>(); foreach (PageUrlAttribute attr2 in regexAttrs) { if (string.IsNullOrEmpty(attr2.Url) == false) { if (actionDescription == null) { actionDescription = CreatePageActionDescription(controller, m); } Regex regex = new Regex(attr2.Url, RegexOptions.Compiled | RegexOptions.IgnoreCase); regexActions.Add(new RegexActionDescription { Regex = regex, ActionDescription = actionDescription }); } } } } PageUrlRegexArray = regexActions.ToArray(); }
private ActionDescription GetServiceAction(Type controller, string action) { if (controller == null) { throw new ArgumentNullException("controller"); } if (string.IsNullOrEmpty(action)) { throw new ArgumentNullException("action"); } // 首先尝试从缓存中读取 string cacheKey = "01_" + _context.Request.HttpMethod + "#" + controller.FullName + "#" + action; ActionDescription mi = (ActionDescription)s_metadata.ServiceActionTable[cacheKey]; if (mi == null) { bool saveToCache = true; MethodInfo method = FindAction(action, controller); if (method == null) { // 如果Action的名字是submit并且是POST提交,则需要自动寻找Action // 例如:多个提交都采用一样的方式:POST /ajax/ns/Product/submit if (action.IsSame("submit") && _context.Request.HttpMethod.IsSame("POST")) { // 自动寻找Action method = FindSubmitAction(controller); saveToCache = false; } } if (method == null) { // 执行诊断测试 if (this.DiagnoseResult != null) { TestActions(action, controller); if (action.IsSame("submit") && _context.Request.HttpMethod.IsSame("POST") == false) { this.DiagnoseResult.ErrorMessages.Add("如果希望使用 submit 做为Action名称自动匹配,HttpMethod必须要求是POST"); } } return(null); } var attr = method.GetMyAttribute <ActionAttribute>() ?? new ActionAttribute(); mi = new ActionDescription(method, attr); if (saveToCache) { s_metadata.ServiceActionTable[cacheKey] = mi; } } return(mi); }