Как получить определенный код для выполнения перед каждым действием одного контроллера в ASP.NET MVC 2?
Я хочу проверить некоторые вещи о состоянии сеанса, пользовательском агенте и т.д., и, возможно, предпринять действия и вернуть специальный вид ДО того, как метод контроллера получает возможность выполнить. Например:
Чаще всего:
Запросы пользователей Главная/Индекс
Система проверяет, чтобы x!= 0.
x не равен нулю, поэтому Home/Index controller выполняется как обычно.
Но, иногда:
Запросы пользователей Главная/Индекс
Система проверяет, чтобы x!= 0.
x равно нулю. Пользователь должен быть уведомлен, и запрошенное действие контроллера не может быть выполнено.
Я думаю, что это связано с использованием ActionFilters. Но я прочитал о них, и я не понимаю, могу ли я вытеснить метод контроллера и вернуть представление до его выполнения. Я уверен, что могу выполнить код перед запуском метода контроллера, но как я могу заставить его работать в некоторых случаях и возвращать пользовательский вид или напрямую обращаться к другому методу контроллера?
Обновление: я реализовал решение RM. Это то, что я сделал:
public class MyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (myValue == wrongValue)
{
filterContext.Result = new ViewResult{ViewName = "Notice"};
}
base.OnActionExecuting(filterContext);
}
}
Теперь, когда myValue ошибочен, эти пользователи получают представление "Уведомление", и запрошенный контроллер никогда не выполняется. Чтобы выполнить эту работу, я применил ее к ControllerBase, которую наследуют все мои контроллеры.
Ответы
Ответ 1
Все зависит от того, что именно вы хотите сделать, и как. Три варианта ниже:
Для этого можно использовать ограничения маршрута. Они выполняются при оценке маршрута в соответствии с.
routes.MapRoute(
"HomeWithConstraint",
"Home/{action}",
new {controller="Home", action="index"},
new { x = new MyCustomRouteConstraint () }
);
// without constraint, i.e. if above didnt pass
routes.MapRoute(
"HomeWithConstraint",
"Home/{action}",
new {controller="Home", action="index"}
);
Тип MyCustomRouteConstraint, указанный выше, будет проверять для x == 0 и т.д. в вашем примере. Не уверен точно, что вы хотите сделать, но это позволит вам проверить условия перед запуском и установить дополнительные значения маршрута и т.д.
См. здесь, например, пользовательских ограничений маршрута.
Альтернативно, да, вы можете использовать собственный ActionFilter, просто примените его к классу контроллера, и он будет вызван до того, как будет выполнено какое-либо действие. Что-то вроде:
public class CheckXActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(x == 0)
{
// do something
// e.g. Set ActionParameters etc
}
else
{
// do something else
}
}
}
Другой вариант - иметь все ваши контроллеры (или соответствующие) наследовать от настраиваемого контроллера, который вы делаете, и переопределить:
OnActionExecuting
Подробнее см. здесь.
Сделать то же самое, что и фильтр, или ограничения маршрутизации.
Ответ 2
Один из способов сделать это - перенаправить на другой ActionMethod, чтобы показать представление. Пример кода приведен в этом обсуждении:
Перенаправление на указанный контроллер и действие в фильтр действий asp.net mvc