Сделайте все методы действия контроллера ChildActionOnly
Вместо того, чтобы не забыть украсить кучу методов действия с ChildActionOnly
атрибут, было бы удобно иметь возможность указывать все методы во всем контроллере как таковые.
Пытаюсь поставить ChildActionOnly
Атрибут в классе контроллера не работает (по крайней мере, в моем контексте кода), потому что во время внедрения зависимостей для контроллеров, которое происходит на ранней стадии в конвейере запросов, нет объекта HttpContext или Request, и появляется ошибка "Запрос недоступно в этом контексте "брошено.
Могу ли я создать RouteConstraint
что заставляет сам маршрут применять ChildActionOnly
? Это кажется сомнительным из-за той же проблемы конвейера запросов - я не знаю, будет ли HttpContext доступен во время выполнения RouteConstraints. Если у вас есть идеи, как это реализовать, пожалуйста, поделитесь.
Может быть, создать модульный тест, который использует отражение, чтобы обнаружить все методы действия конкретного контроллера и убедиться, что они имеют ChildActionOnly
набор атрибутов...
Как мне это сделать? Не могли бы вы дать какой-нибудь стартовый код (не нужно полировать или даже работать, только начальная точка поможет).
2 ответа
Как насчет фильтров? Вы можете создать свой собственный фильтр, а затем просто добавить фильтр в FilterConfig. Фильтры в MVC позволяют добавлять бизнес-логику (код) до / после выполнения действия, в примере для каждого запроса к действию сначала выполняется, а затем действие, и вы можете получить доступ к:
HttpContext.Current.Session filterContext.HttpContext.Request
и вы можете перенаправить
filterContext.Result = new RedirectResult.
Существуют различные типы фильтров: 1. Фильтры аутентификации (Новое в ASP.NET MVC5) 2. Фильтры авторизации 3. Фильтры действий 4. Фильтры результатов 5. Фильтры исключений
в приведенном ниже примере я создаю пользовательский фильтр для авторизации
public class CustomFilter : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (!UserRepository.IsValidUserBy(HttpContext.Current.Session["userName"].ToString()))
{
filterContext.Result = new RedirectResult("~/User/AccessDenied", true);
}
}
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new MyExpirePageActionFilterAttribute());
filters.Add(new CustomFilter ());
}
Я нашел этот вопрос и ответ, пока гуглял, как добиться именно этого сам.
Хотя этот вопрос касается конкретно MVC4, и мой ответ не имеет к этому непосредственного отношения, все же представляется уместным указать, что MVC 5 теперь поддерживает использование [ChildActionOnly]
атрибут на весь контроллер, что делает возможным следующее:
namespace MyWebApp.Controllers
{
[ChildActionOnly]
public class MyController
{
//Can only be called from another action
public ActionResult MyAction()
{
return View();
}
}
}
который при переходе непосредственно к http://myapp.com/MyController/MyAction приводит к возвращению следующего:
Server Error in '/' Application. The action 'MyAction' is accessible only by a child request. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace
Для получения дополнительной информации об ошибке и ее возникновении в коде.
Exception Details: System.InvalidOperationException: The action 'MyAction' is accessible only by a child request.