以下是示例操作过滤器。我们知道当我们编写一个动作过滤器时,我们需要用这样的属性来装饰控制器,以便将它用于任何控制器。
我想知道是否有任何方法可以编写一个动作过滤器,它可以用于所有控制器,我不需要使用动作过滤器属性来装饰所有控制器。有什么想法吗?
[LogActionFilter]
public class HomeController : Controller
{}
public class LogActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}
private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
Debug.WriteLine(message, "Action Filter Log");
}
}
答案 0 :(得分:11)
public class LogActionFilterAttribute : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}
private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
Debug.WriteLine(message, "Action Filter Log");
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalFilters.Filters.Add(new LogActionFilterAttribute());
}
}
答案 1 :(得分:3)
对于您的方案,您只需创建自定义BaseController 并将您的[LogActionFilter]
属性放在自定义Basecontroller 上,并从自定义Basecontroller继承所有控制器,如下所示:
[LogActionFilter]
public class MyBaseController : Controller
{
}
public class MyOtherController : MyBaseController //<----instead of using Controller as base use MyBaseController as base class
{
public ActionResult Index()
{
// ...
}
}
此方法的优点是您必须将自定义[LogActionFilter]
属性仅放在一个位置,即仅在自定义BaseController上。
答案 2 :(得分:1)
如果您已经从基本控制器继承子类,则不需要过滤器属性或注册任何内容。您可以覆盖所需的方法,例如,
public class BaseController : Controller {
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
ViewBag.SomeValue = "glorp frob blizz nunk";
// Access the controller, parameters, querystring, etc. from the filterContext
base.OnActionExecuting(filterContext);
}
}
然后,从其子类化的每个控制器都将运行该方法:
public sealed class GlorpController : BaseController {
public ActionResult Index() => View();
}
视图很高兴看到ViewBag.SomeValue
值。