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;
		}
Esempio n. 5
0
        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);
        }