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; } } }