Beispiel #1
0
        private Routing GetMatchedRoute(RouteValueDictionary routeValues)
        {
            var url = UriExtensions.MakeRelativeFromUrl(routeValues.Values.Select(x => (x?.ToString() ?? "").TrimEnd('/')).First().ToString()).ToLower();

            if (url.Trim() == "/")
            {
                return(null);
            }

            if (_dbCache.TryGetValue(url, out Routing data))
            {
                return(data);
            }

            using (var db = new OnUtils.Data.UnitOfWork <Routing>())
            {
                // Вложенный запрос работает долю секунды. А предыдущий вариант с условием и сортировкой внутри одного селекта работает значительно дольше.
                var queryRoutes = db.DataContext.ExecuteQuery <Routing>($@"
                    SELECT *
                    FROM [dbo].[UrlTranslation]
                    WHERE IdTranslation = (
                        SELECT top (1) [IdTranslation]
                        FROM [dbo].[UrlTranslation]
                        WHERE ([UrlFull] LIKE @Url + '%' AND [IsFixedLength] <> 1) OR ([UrlFull] = @Url AND [IsFixedLength] = 1)
                        ORDER BY CASE WHEN (1 = [IdTranslationType]) THEN 0 ELSE 1 END ASC, [IsFixedLength] ASC, LEN([UrlFull]) DESC, [DateChange] DESC, [IdTranslation] DESC
                    )
                ", new { Url = url });

                var route = queryRoutes.FirstOrDefault();

                //EF генерит неправильное определение для url.StartsWith(x.UrlFull) в виде CHARINDEX вместо LIKE, из-за чего запрос выполняется дольше секунды.
                //Пока что не получилось заставить его делать как надо.
                //var routes = DB.Routing
                //    .Where(x => (url.StartsWith(x.UrlFull) && !x.IsFixedLength) || (url == x.UrlFull && x.IsFixedLength))
                //    .OrderBy(x => x.IdRoutingType == RoutingType.eTypes.Main ? 0 : 1)
                //    .ThenBy(x => x.IsFixedLength)
                //    .ThenByDescending(x => x.UrlFull.Length)
                //    .ThenByDescending(x => x.DateChange)
                //    .Take(2);

                //var list = routes.ToList();

                if (route != null)
                {
                    _dbCache.SetWithExpiration(url, route, TimeSpan.FromMilliseconds(5));
                    return(route);
                }
            }

            return(null);
        }
        public IController CreateController(RequestContext requestContext, string moduleName)
        {
            requestContext.HttpContext.Items["TimeController"] = DateTime.Now;

            var isAjax = false;

            // Проверка на авторизацию. Ловим случаи, когда авторизация не сработала в HttpApplication.
            var context = AppCore.GetUserContextManager().GetCurrentUserContext();

            if (context.IsGuest)
            {
                var sessionBinder = AppCore.Get <SessionBinder>();
                context = sessionBinder.RestoreUserContextFromRequest();
                if (context != null && !context.IsGuest)
                {
                    AppCore.Get <OnWeb.Modules.Auth.ModuleAuth>()?.RegisterEvent(EventType.CriticalError, "Нарушение процесса авторизации", null);
                    AppCore.GetUserContextManager().SetCurrentUserContext(context);
                }
            }

            IModuleCore module = null;

            try
            {
                /*
                 * Определение языка и темы
                 */
                {
                    var lang = string.Format("{0}", requestContext.RouteData.Values["language"]);

                    using (var db = this.CreateUnitOfWork())
                    {
                        var query = from Language in db.Language
                                    where Language.IsDefault != 0 || Language.ShortAlias == lang
                                    orderby(Language.ShortAlias == lang? 1 : 0) descending
                                    select Language;

                        var data = query.ToList();
                        //var sql = DB.DataContext.ExecuteQuery<DB.Language>(@"
                        //    SELECT TOP(1) *
                        //    FROM Language
                        //    WHERE IsDefault <> 0 OR ShortAlias = '" + DataManager.prepare(lang) + @"'
                        //    ORDER BY CASE WHEN ShortAlias = '" + DataManager.prepare(lang) + @"' THEN 1 ELSE 0 END DESC
                        //");
                        if (data.Count > 0)
                        {
                            var res = data.First();
                            requestContext.RouteData.Values["language"] = res.ShortAlias;
                        }
                    }
                }

                /*
                 * Ищем модуль, к которому обращаются запросом.
                 * */
                if (int.TryParse(moduleName, out int moduleId) && moduleId.ToString() == moduleName)
                {
                    module = (IModuleCore)AppCore.GetModulesManager().GetModule(moduleId);
                }
                else if (Guid.TryParse(moduleName, out Guid uniqueName) && uniqueName.ToString() == moduleName)
                {
                    module = (IModuleCore)AppCore.GetModulesManager().GetModule(uniqueName);
                }
                else
                {
                    module = (IModuleCore)AppCore.GetModulesManager().GetModule(moduleName);
                }

                if (module == null)
                {
                    throw new ErrorCodeException(HttpStatusCode.NotFound, $"Адрес '{moduleName}' не найден.");
                }

                /*
                 * Ищем контроллер, который относится к модулю.
                 * */
                var controllerType = ControllerTypeFactory.RoutingPrepareURL(requestContext.HttpContext.Request, UriExtensions.MakeRelativeFromUrl(requestContext.HttpContext.Request.Url.PathAndQuery));

                if (requestContext.RouteData.Route is Route)
                {
                    /*
                     * Анализируем адрес и устанавливаем признак, если это вызов в панель управления. Пришлось пойти на такой хак.
                     * */
                    var route = requestContext.RouteData.Route as Route;
                    if (route.Url.StartsWith("admin/madmin"))
                    {
                        isAjax = true;
                    }

                    if (isAjax)
                    {
                        HttpContext.Current.Items["isAjax"] = true;
                    }
                }

                var controller = CreateController(controllerType, module, requestContext.RouteData.Values);
                HttpContext.Current.Items["RequestContextController"] = controller;
                return(controller);
            }
            catch (Exception ex)
            {
                try
                {
                    if (module == null)
                    {
                        var moduleTmp = new ModuleInternalErrors();
                        ((IComponentStartable)moduleTmp).Start(AppCore);
                        module = moduleTmp;
                    }

                    var type       = typeof(ModuleControllerInternalErrors <>).MakeGenericType(module.GetType());
                    var controller = CreateController(module, type, requestContext.RouteData.Values);
                    (controller as IModuleControllerInternalErrors).SetException(ex);
                    // todo (controller as Modules.ModuleController).IsAdminController = isErrorAdmin;

                    HttpContext.Current.Items["RequestContextController"] = controller;
                    return(controller);
                }
                catch (Exception ex2)
                {
                    Debug.WriteLine("Throw: {0}", ex2.ToString());
                    throw ex;
                }
            }
        }