Esempio n. 1
0
        // 说明:命名空间中和类名之间可以用 / 和 . 分隔,但是在<system.web>/<httpHandlers>节点中要注意 / 出现的次数与URL中的次数匹配
        //        IIS的集成模式没有这个问题。

        // 补充说明:以上正则表示式当遇到REST风格时,如果在method位置包含了非字符类的文字作为方法的传入参数,匹配后将会造成数据丢失。
        //          因为是采用的 (?<method>\w+) ,除非换成 (?<method>[^\.]+) ,并且在得到数据后做UrlDecode


        /*
         * 可以解析以下格式的URL:(前一个表示包含命名空间的格式)
         *
         * /service/namespace.Fish.AA.Demo/GetMd5.aspx
         * /service/namespace.Fish.AA/Demo/GetMd5.aspx
         * /service/Demo/GetMd5.aspx
         * /api/aa/Demo/GetMd5
         * /api/aa.b/Demo/GetMd5?ss=a.b
         */


        /// <summary>
        /// 从指定的请求中提取UrlActionInfo
        /// </summary>
        /// <param name="context"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public virtual UrlActionInfo GetUrlActionInfo(HttpContext context, string path)
        {
            // 扩展点:允许自定义URL解析逻辑

            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

            Match match = ServiceUrlRegex.Match(path);

            if (match.Success == false)
            {
                DiagnoseResult diagnoseResult = Http404DebugModule.TryGetDiagnoseResult(context);
                if (diagnoseResult != null)
                {
                    diagnoseResult.ErrorMessages.Add("URL解析失败,正则表达式:" + ServiceUrlRegex.ToString());
                }

                return(null);
            }

            return(new UrlActionInfo {
                UrlType = match.Groups["type"].Value,
                Namesapce = match.Groups["namespace"].Value,
                ClassName = match.Groups["name"].Value,
                MethodName = match.Groups["method"].Value,
                ExtName = match.Groups["extname"].Value
            });
        }
Esempio n. 2
0
        internal IHttpHandler GetHttpHandler(HttpContext context, UrlActionInfo info)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }


            // 获取内部表示的调用信息
            ControllerResolver controllerResolver = new ControllerResolver(context);
            InvokeInfo         vkInfo             = controllerResolver.GetActionInvokeInfo(info);

            if (vkInfo == null)
            {
                IHttpHandler handler = Http404DebugModule.TryGetHttp404PageHandler(context);
                if (handler != null)
                {
                    return(handler);
                }
                else
                {
                    return(null);
                }
            }


            // 创建能够调用Action的HttpHandler
            return(ActionHandlerFactory.CreateHandler(vkInfo));
        }
Esempio n. 3
0
        internal ControllerResolver(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            _context       = context;
            DiagnoseResult = Http404DebugModule.TryGetDiagnoseResult(context);

            s_metadata.Init();
        }
        /// <summary>
        /// 实现IHttpHandlerFactory接口,从当前请求获取IHttpHandler
        /// </summary>
        /// <param name="context"></param>
        /// <param name="requestType"></param>
        /// <param name="virtualPath"></param>
        /// <param name="physicalPath"></param>
        /// <returns></returns>
        public IHttpHandler GetHandler(HttpContext context,
                                       string requestType, string virtualPath, string physicalPath)
        {
            // 说明:这里不使用virtualPath变量,因为不同的配置,这个变量的值会不一样。
            // 例如:/Ajax/*/*.aspx 和 /Ajax/*
            // 为了映射HTTP处理器,下面直接使用context.Request.Path

            string vPath = context.GetRealVirtualPath();



            // 根据请求路径,定位到要执行的Action
            UrlActionInfo info = ParseUrl(context, vPath);

            if (info == null)
            {
                IHttpHandler handler = Http404DebugModule.TryGetHttp404PageHandler(context);
                if (handler != null)
                {
                    return(handler);
                }

                ExceptionHelper.Throw404Exception(context);
            }

            info.SetHttpcontext(context);



            // 获取内部表示的调用信息
            ControllerResolver controllerResolver = new ControllerResolver(context);
            InvokeInfo         vkInfo             = controllerResolver.GetActionInvokeInfo(info);

            if (vkInfo == null)
            {
                IHttpHandler handler = Http404DebugModule.TryGetHttp404PageHandler(context);
                if (handler != null)
                {
                    return(handler);
                }

                ExceptionHelper.Throw404Exception(context);
            }

            // 创建能够调用Action的HttpHandler
            return(ActionHandlerFactory.CreateHandler(vkInfo));
        }
        public void Test2()
        {
            string requestText = @"
POST http://www.fish-mvc-demo.com/Ajax/test/DataTypeTest/xxxxxxxxxxx.aspx HTTP/1.1
";
            // 上面URL指定了一个不存在的Action名称,会引发404错误

            IHttpHandler       handler     = null;
            Http404DebugModule debugModule = new Http404DebugModule();

            using (WebContext context = WebContext.FromRawText(requestText)) {
                debugModule.app_BeginRequest(context.Application.Instance, null);

                var factory = new ServiceHandlerFactory();
                handler = factory.GetHandler(context.HttpContext, "POST", null, null);
            }

            Assert.IsInstanceOfType(handler, typeof(Http404PageHandler));
        }
Esempio n. 6
0
        /// <summary>
        /// 实现IRouteHandler接口
        /// </summary>
        /// <param name="requestContext"></param>
        /// <returns></returns>
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            HttpContext context = requestContext.HttpContext.ApplicationInstance.Context;

            UrlActionInfo info = GetUrlActionInfo(requestContext.RouteData, context);

            if (info == null)
            {
                IHttpHandler handler = Http404DebugModule.TryGetHttp404PageHandler(context);
                if (handler != null)
                {
                    return(handler);
                }

                ExceptionHelper.Throw404Exception(context);
            }

            info.SetHttpcontext(context);

            return(GetHttpHandler(context, info));
        }
        IHttpHandler IHttpHandlerFactory.GetHandler(HttpContext context,
                                                    string requestType, string virtualPath, string physicalPath)
        {
            // 说明:这里不使用virtualPath变量,因为不同的配置,这个变量的值会不一样。
            // 例如:/mvc/*/*.aspx 和 /mvc/*
            // 为了映射HTTP处理器,下面直接使用context.Request.Path

            string requestPath = context.Request.Path;
            string vPath       = context.GetRealVirtualPath();

            // 尝试根据请求路径获取Action
            ControllerResolver controllerResolver = new ControllerResolver(context);
            InvokeInfo         vkInfo             = controllerResolver.GetActionInvokeInfo(vPath);

            // 如果没有找到合适的Action,并且请求的是一个ASPX页面,则按ASP.NET默认的方式来继续处理
            if (vkInfo == null)
            {
                if (requestPath.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase))
                {
                    // 调用ASP.NET默认的Page处理器工厂来处理
                    try {
                        return(_msPageHandlerFactory.GetHandler(context, requestType, requestPath, physicalPath));
                    }
                    catch (Exception ex) {
                        if (controllerResolver.DiagnoseResult != null)
                        {
                            controllerResolver.DiagnoseResult.ErrorMessages.Add("System.Web.UI.PageHandlerFactory不能根据指定的URL地址创建IHttpHandler实例。");
                            controllerResolver.DiagnoseResult.ErrorMessages.Add(ex.Message);

                            return(Http404DebugModule.TryGetHttp404PageHandler(context));
                        }

                        throw;
                    }
                }
            }

            return(ActionHandlerFactory.CreateHandler(vkInfo));
        }
        private RouteData GetRoute(HttpContext context, string virtualPath)
        {
            HttpContextWrapper contextWrapper = new HttpContextWrapper(context);


            // 利用ASP.NET Routing解析URL
            RouteData routeData = RouteTable.Routes.GetRouteData(contextWrapper);

            if (routeData == null)
            {
                DiagnoseResult diagnoseResult = Http404DebugModule.TryGetDiagnoseResult(context);
                if (diagnoseResult != null)
                {
                    diagnoseResult.ErrorMessages.Add("URL不能与任何路由配置(RouteTable)匹配:" + virtualPath);
                    diagnoseResult.RouteTestResult = (from x in RouteTable.Routes
                                                      let route = x as Route
                                                                  where route != null
                                                                  select new TestResult {
                        Text = route.Url, IsPass = false
                    }).ToList();
                }
                return(null);
            }

            if (routeData.RouteHandler != null && routeData.RouteHandler is StopRoutingHandler)
            {
                DiagnoseResult diagnoseResult = Http404DebugModule.TryGetDiagnoseResult(context);
                if (diagnoseResult != null)
                {
                    diagnoseResult.ErrorMessages.Add("路由匹配成功,结果是一个StopRoutingHandler");
                }

                return(null);
            }

            return(routeData);
        }
Esempio n. 9
0
        internal UrlActionInfo GetUrlActionInfo(RouteData routeData, HttpContext context)
        {
            if (routeData == null)
            {
                throw new ArgumentNullException("routeData");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            // 采用ASP.NET Routing后,这三个参数都应该可以直接获取到,
            // 如果URL没有指定,可以通过默认值,或者DataToken指定,
            // 所以不需要像RestServiceModule那样重新计算
            string nspace    = GetRouteString(routeData, "namespace");
            string className = GetRouteString(routeData, "controller");
            string action    = GetRouteString(routeData, "action");

            if (string.IsNullOrEmpty(className) || string.IsNullOrEmpty(action))
            {
                DiagnoseResult diagnoseResult = Http404DebugModule.TryGetDiagnoseResult(context);
                if (diagnoseResult != null)
                {
                    diagnoseResult.ErrorMessages.Add("不能从URL中提取到controller和action信息");
                }

                return(null);
            }

            if (action == "{HttpMethod}")                       // 允许定义这个特殊变量
            {
                action = context.Request.HttpMethod;
            }


            ControllerResolver controllerResolver = new ControllerResolver(context);

            UrlActionInfo info = new UrlActionInfo();

            info.RoutePattern = (routeData.Route as Route).Url;                         // 转换失败??
            info.Namesapce    = controllerResolver.GetNamespaceMap(nspace);
            info.ClassName    = className;
            info.MethodName   = action;

            info.Action     = action;
            info.Controller = s_recognizer.GetServiceFullName(info);


            // 将路由提取到的其它URL参数,保存到UrlActionInfo实例中。
            foreach (KeyValuePair <string, object> kvp in routeData.Values)
            {
                // 排除3个特定名字。
                if (kvp.Key.IsSame("namespace") || kvp.Key.IsSame("controller") || kvp.Key.IsSame("action"))
                {
                    continue;
                }

                string value = kvp.Value as string;
                if (string.IsNullOrEmpty(value) == false)
                {
                    info.AddParam(kvp.Key, value);
                }
            }

            return(info);
        }