GVKun编程网logo

asp.net-mvc-4 – MVC4自定义OnActionExecuting Global.asx过滤器未被触发(添加自定义过滤器错误)

14

在本文中,我们将为您详细介绍asp.net-mvc-4–MVC4自定义OnActionExecutingGlobal.asx过滤器未被触发的相关知识,并且为您解答关于添加自定义过滤器错误的疑问,此外,

在本文中,我们将为您详细介绍asp.net-mvc-4 – MVC4自定义OnActionExecuting Global.asx过滤器未被触发的相关知识,并且为您解答关于添加自定义过滤器错误的疑问,此外,我们还会提供一些关于asp.net core MVC 过滤器之ActionFilter过滤器(2)、asp.net core MVC 过滤器之ActionFilter过滤器(二)、ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值、ASP.NET MVC ActionFilter自定义过滤器异常过滤器过滤器用法的有用信息。

本文目录一览:

asp.net-mvc-4 – MVC4自定义OnActionExecuting Global.asx过滤器未被触发(添加自定义过滤器错误)

asp.net-mvc-4 – MVC4自定义OnActionExecuting Global.asx过滤器未被触发(添加自定义过滤器错误)

我正在尝试创建一个全局过滤器,该过滤器将针对用户登录时的每个操作运行.从我所看到的,有两个必要的步骤.首先,在Global.asx文件中添加新过滤器.

public class MvcApplication : System.Web.HttpApplication
{
    //I added this
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new NotificationFilter());
    }
    protected void Application_Start()
    {
        AreaRegistration.RegisterallAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.Registerauth();
    }
}

然后我必须在filters文件夹中创建过滤器.

public class NotificationFilter : ActionFilterattribute 
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    { //Breakpoint here is never triggered
        //This code doesn't work,but it's what I want to do
        if (WebSecurity.CurrentUserId > 0)
        {
            var notificationCount = db.Notifications.GroupBy(i => i.UserID).Count();
            if (notificationCount > 99)
            {
                ViewBag.Notifications = "99+";
            }
            else
            {
                ViewBag.Notifications = notificationCount;
            }
        }
        base.OnActionExecuting(filterContext);
    }
}

我怎样才能做到这一点?有没有更好的办法?我可以将它添加到所有控制器并且它可以工作,这不太理想.

解决方法

我有同样的经历.您可以构建一个BaseController类并将过滤器定义放入其中.然后,所有控制器必须从BaseController类继承.因此,您不必在所有控制器中使用过滤器类.

这样的事情:

public class BaseController : Controller
    {

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
         ...
         }
    }

在控制器中:

public class SampleController : BaseController
{
 ...
}

asp.net core MVC 过滤器之ActionFilter过滤器(2)

asp.net core MVC 过滤器之ActionFilter过滤器(2)

简介

Action过滤器将在controller的Action执行之前和之后执行相应的方法。

实现一个自定义Action过滤器

自定义一个全局异常过滤器需要实现IActionFilter接口

public class ActionFilter : IActionFilter
{
  public void OnActionExecuted(ActionExecutedContext context)
  {
    Console.WriteLine("action执行之后");
  }

  public void OnActionExecuting(ActionExecutingContext context)
  {
    Console.WriteLine("action执行之前");
  }
}

IActionFilter需要实现两个方法OnActionExecuted,OnActionExecuting。OnActionExecuting将在Action之前执行,OnActionExecuted在Action之后执行。

知道原理之后我们们就可以利用其特性来简化我们的代码,在MVC中一个重要的概念就时Model验证,我们定义Model约束,然后在Action中验证Model是否绑定成功,我们的Action中重复地写如下代码

[HttpGet]
public ActionResult Get()
{
  if (!ModelState.IsValid) return BadRequest("参数错误!");
}

这样重复的代码不仅增加代码复杂都也不美观,我们可以在ActionFilter中自动完成

public void OnActionExecuting(ActionExecutingContext context)
{
  if (context.ModelState.IsValid) return;

  var modelState = context.ModelState.FirstOrDefault(f => f.Value.Errors.Any());
  string errorMsg = modelState.Value.Errors.First().ErrorMessage;
  throw new AppException(errorMsg);
}

当Model绑定错误时,我们抛出异常信息,并在上一章节的异常过滤器ExceptionFilter中捕获,返回错误信息给请求方。

我们也可以利用ActionFilter的特性来记录Action的执行时间,当Action执行时间过慢时输出警告日志

public class ActionFilter : IActionFilter
{
  public void OnActionExecuted(ActionExecutedContext context)
  {
    var httpContext = context.HttpContext;
    var stopwach = httpContext.Items[Resources.StopwachKey] as Stopwatch;
    stopwach.Stop();
    var time = stopwach.Elapsed;

    if (time.TotalSeconds > 5)
    {
      var factory = context.HttpContext.RequestServices.GetService<ILoggerFactory>();
      var logger = factory.CreateLogger<ActionExecutedContext>();
      logger.LogWarning($"{context.ActionDescriptor.DisplayName}执行耗时:{time.ToString()}");
    }
  }

  public void OnActionExecuting(ActionExecutingContext context)
  {
    var stopwach = new Stopwatch();
    stopwach.Start();
    context.HttpContext.Items.Add(Resources.StopwachKey, stopwach);
  }
}

上面的代码利用使用HttpContext传递一个Stopwach来计算action的执行时间,并在超过5秒时输出警告日志。 

注册全局过滤器

注册方法与ExceptionFinter相同。找到系统根目录Startup.cs文件,修改ConfigureServices方法如下

services.AddMvc(options =>
      {
        options.Filters.Add<ActionFilter>();
      });

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • ASP.NET过滤器的应用方法介绍
  • asp.net core MVC 全局过滤器之ExceptionFilter过滤器(1)
  • Asp.Net MVC学习总结之过滤器详解
  • ASP.NET Core MVC 过滤器的使用方法介绍
  • ASP.NET mvc4中的过滤器的使用
  • ASP.NET Core MVC 过滤器(Filter)
  • ASP.NET MVC授权过滤器用法
  • ASP.NET MVC自定义异常过滤器
  • ASP.NET MVC异常过滤器用法
  •  ASP.NET Core 模型验证过滤器的两种实现方法

asp.net core MVC 过滤器之ActionFilter过滤器(二)

asp.net core MVC 过滤器之ActionFilter过滤器(二)

简介

Action过滤器将在controller的Action执行之前和之后执行相应的方法。

实现一个自定义Action过滤器

自定义一个全局异常过滤器需要实现IActionFilter接口

复制代码
public class ActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        Console.WriteLine("action执行之后");
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        Console.WriteLine("action执行之前");
    }
}
复制代码

IActionFilter需要实现两个方法OnActionExecuted,OnActionExecuting。OnActionExecuting将在Action之前执行,OnActionExecuted在Action之后执行。

知道原理之后我们们就可以利用其特性来简化我们的代码,在MVC中一个重要的概念就时Model验证,我们定义Model约束,然后在Action中验证Model是否绑定成功,我们的Action中重复地写如下代码

 

[HttpGet]
public ActionResult Get()
{
    if (!ModelState.IsValid) return BadRequest("参数错误!");
}

 这样重复的代码不仅增加代码复杂都也不美观,我们可以在ActionFilter中自动完成

 

复制代码
public void OnActionExecuting(ActionExecutingContext context)
{
    if (context.ModelState.IsValid) return;

    var modelState = context.ModelState.FirstOrDefault(f => f.Value.Errors.Any());
    string errorMsg = modelState.Value.Errors.First().ErrorMessage;
    throw new AppException(errorMsg);
}
复制代码

当Model绑定错误时,我们抛出异常信息,并在上一章节的异常过滤器ExceptionFilter中捕获,返回错误信息给请求方。

我们也可以利用ActionFilter的特性来记录Action的执行时间,当Action执行时间过慢时输出警告日志

 

复制代码
public class ActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        var httpContext = context.HttpContext;
        var stopwach = httpContext.Items[Resources.StopwachKey] as Stopwatch;
        stopwach.Stop();
        var time = stopwach.Elapsed;

        if (time.TotalSeconds > 5)
        {
            var factory = context.HttpContext.RequestServices.GetService<ILoggerFactory>();
            var logger = factory.CreateLogger<ActionExecutedContext>();
            logger.LogWarning($"{context.ActionDescriptor.DisplayName}执行耗时:{time.ToString()}");
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        var stopwach = new Stopwatch();
        stopwach.Start();
        context.HttpContext.Items.Add(Resources.StopwachKey, stopwach);
    }
}
复制代码

上面的代码利用使用HttpContext传递一个Stopwach来计算action的执行时间,并在超过5秒时输出警告日志。

 

注册全局过滤器

注册方法与ExceptionFinter相同。找到系统根目录Startup.cs文件,修改ConfigureServices方法如下

services.AddMvc(options =>
            {
                options.Filters.Add<ActionFilter>();
            });

ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值

ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值

用过ASP.NET Core MVC中IActionFilter拦截器的开发人员,都知道这是一个非常强大的MVC拦截器。最近才发现IActionFilter的OnActionExecuting方法,甚至可以获取Controller的Action方法参数值。

 

假如我们在ASP.NET Core MVC项目中有一个HomeController,其中有一个Action方法叫Login,该方法有一个LoginLogoutRequest类型的参数,注意我们在Login上注册了我们后面会讲解的MyActionFilter拦截器:

public class HomeController : Controller
{
    [MyActionFilter]
    [HttpPost]
    public IActionResult Login([FromBody]LoginLogoutRequest loginLogoutRequest)
    {
        return View();
    }
}

其参数LoginLogoutRequest类的定义如下:

public class LoginLogoutRequest
{
    public string Username { get; set; }
    public string Password { get; set; }

}

 

那么我们可以定义一个IActionFilter拦截器叫MyActionFilter,在其OnActionExecuting方法中,来获取HomeController中Action方法Login的参数LoginLogoutRequest:

public class MyActionFilterAttribute : Attribute, IActionFilter
{
    /// <summary>
    /// OnActionExecuting方法在Controller的Action执行前执行
    /// </summary>
    public void OnActionExecuting(ActionExecutingContext context)
    {
        //循环获取在Controller的Action方法中定义的参数
        foreach (var parameter in context.ActionDescriptor.Parameters)
        {
            var parameterName = parameter.Name;//获取Action方法中参数的名字
            var parameterType = parameter.ParameterType;//获取Action方法中参数的类型

            //判断该Controller的Action方法是否有类型为LoginLogoutRequest的参数
            if (parameterType == typeof(LoginLogoutRequest))
            {
                //如果有,那么就获取LoginLogoutRequest类型参数的值
                var loginLogoutRequest = context.ActionArguments[parameterName] as LoginLogoutRequest;

                var username = loginLogoutRequest.Username;
                var password = loginLogoutRequest.Password;
            }
        }
    }

    /// <summary>
    /// OnActionExecuted方法在Controller的Action执行后执行
    /// </summary>
    public void OnActionExecuted(ActionExecutedContext context)
    {
        //TODO
    }
}

可以看到在IActionFilter的OnActionExecuting方法中,通过很简单的代码,我们就可以获取到Login方法参数LoginLogoutRequest的值。

 

ASP.NET MVC ActionFilter自定义过滤器异常过滤器过滤器用法

ASP.NET MVC ActionFilter自定义过滤器异常过滤器过滤器用法

自定义过滤器使用非常灵活,可以精确的注入到请求前、请求中和请求后。继承抽象类ActionFilterAttribute并重写里面的方法即可:

public class SystemLogAttribute : ActionFilterAttribute

{

    public string Operate { get; set; }


    public override void OnActionExecuted(ActionExecutedContext filterContext)

    {

        filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnActionExecuted");

        base.OnActionExecuted(filterContext);

    }


    public override void OnActionExecuting(ActionExecutingContext filterContext)

    {

        filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnActionExecuting");

        base.OnActionExecuting(filterContext);

    }


    public override void OnResultExecuted(ResultExecutedContext filterContext)

    {

        filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnResultExecuted");

        base.OnResultExecuted(filterContext);

    }


    public override void OnResultExecuting(ResultExecutingContext filterContext)

    {

        filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnResultExecuting");

        base.OnResultExecuting(filterContext);

    }

}

这个过滤器适合做系统操作日志记录功能:

[SystemLog(Operate = "添加用户")]

public string CustomerFilterTest()

{

    Response.Write("<br/>Action 执行中...");

    return "<br/>Action 执行结束";

}

看下结果:

四个方法执行顺序:OnActionExecuting—>OnActionExecuted—>OnResultExecuting—>OnResultExecuted,非常精确的控制了整个请求过程。

实际开发中中记录日志过程是这样的:在OnActionExecuting方法里写一条操作日志到数据库里,全局变量存下这条记录的主键,到OnResultExecuted方法里说明请求结束了,这个时候自然知道用户的这个操作是否成功了,根据主键更新下这条操作日志的是否成功字段。



本文分享自微信公众号 - IT技术分享社区(gh_a27c0758eb03)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

关于asp.net-mvc-4 – MVC4自定义OnActionExecuting Global.asx过滤器未被触发添加自定义过滤器错误的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于asp.net core MVC 过滤器之ActionFilter过滤器(2)、asp.net core MVC 过滤器之ActionFilter过滤器(二)、ASP.NET Core MVC中的IActionFilter.OnActionExecuting方法,可以获取Controller的Action方法参数值、ASP.NET MVC ActionFilter自定义过滤器异常过滤器过滤器用法等相关内容,可以在本站寻找。

本文标签:

上一篇asp.net – Application_AuthenticateRequest总是在Session_Start之前吗?(asp.net_sessionid)

下一篇razor – 使用ActionLink将null参数传递给控制器(java null作为参数传递)