Сначала я подумал, что это может быть так же просто, как добавить новый маршрут, подобный этому:
routes.MapRoute(
"Admin",
"Admin/{*pathInfo}",
new { controller="Admin", action="Index", pathInfo="" }
);
, а затем иметь контроллер примерно так:
public class AdminController : Controller
{
public ActionResult Index(string pathInfo)
{
//Do admin checks, etc here....
return Redirect("/" + pathInfo);
}
}
Однако, к сожалению, все опции, доступные вам для выполнения перенаправления (т. Е. Redirect, RedirectToAction и RedirectToRoute), выполняют перенаправление в стиле 302. По сути, это означает, что ваш /Admin/Product/Whatever
будет выполнен, а затем вернется к браузеру, сообщив ему перенаправить на /Product/Whatever
в совершенно новом запросе, что означает, что вы потеряли свой контекст. Я не знаю чистого способа сохранить серверную часть перенаправления (т. Е. Как Server.Transfer
старого), очевидно, и сообщество SO ...
(очевидно, это не решение, поскольку оно не решает вашу проблему, но я решил поставить его здесь в любом случае, на случай, если вы сможете использовать идеи каким-либо другим способом)
Итак, каково же реальное решение проблемы? Другая идея заключается в использовании ActionFilter (да, я знаю, что вы сказали, что не хотите этого делать, но я думаю, что следующее поможет вам цели). Добавить новый маршрут, как это:
routes.MapRoute(
"Admin",
"Admin/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "", userLevel = "Admin" }
);
, а затем добавьте такой ActionFilter (который вы могли бы применить ко всем запросам через объект базового контроллера, как вы упомянули):
public class ExtendedAdminViewAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
object userLevel = filterContext.RouteData.Values["userLevel"];
if (userLevel != null && userLevel.ToString() == "Admin")
{
//Do your security auth checks to ensure they really are an admin
//Then do your extra admin logic...
}
}
}
Таким образом, хотя он использует ActionFilter, который будет применяться ко всем запросам, единственная дополнительная работа, выполняемая в большинстве обычных случаев (например, запрос на /Product/Whatever
), - это одиночная проверка этого бита данных маршрута (userLevel
). Другими словами, вы действительно должны увидеть снижение производительности для обычных пользователей, поскольку вы выполняете только полную проверку подлинности и дополнительную работу администратора, если они запрашивают через /Admin/Product/Whatever
.