【问题标题】:How to get controller value in Action filter in Web API如何在 Web API 的操作过滤器中获取控制器值
【发布时间】:2019-09-02 04:02:09
【问题描述】:

我正在使用以下代码在 Web API 中执行审计功能:

   [HttpGet]
    public IHttpActionResult GetList()
    {
        //var dd = ((ClaimsIdentity) User.Identity).Claims.FirstOrDefault(x => x.Type == "UserId").Value;

        AuditBAL auditBAL = new AuditBAL();

        Audit audit = new Audit();
        audit.TableName = TableName.Terms_TABLE;
        audit.MenuId = Convert.ToInt64(PageEnum.Terms);
        audit.ActionId = Convert.ToInt64(ActionEnum.List);
        audit.UserId = Convert.ToInt64(((ClaimsIdentity) User.Identity).Claims.FirstOrDefault(x => x.Type == "UserId").Value);

        auditBAL.Save(audit);

        return Ok(new ResponceView<DataTable>()
        {
            ResponseObject = termBAL.GetList()
        });
    }

使用上述方法我可以审计所有事件,但我必须为所有控制器方法编写上述代码审计代码。

我希望它对所有方法通用所以我在 Web API 中使用动作过滤器,但我不知道如何在动作过滤器中获取传递审核对象或如何在动作过滤器中获取方法名称和控制器名称。一旦我将在操作过滤器中获得必要的信息,我就可以使用这些信息进行审核。

我想为异常过滤器做同样的事情(想在异常过滤器中获取方法名称和控制器名称)。

提前致谢。

【问题讨论】:

    标签: asp.net-web-api asp.net-web-api2


    【解决方案1】:

    如何在动作过滤器中获取方法名和控制器名和 异常过滤器


       public class ActionDetailAttribute : System.Web.Http.Filters.ActionFilterAttribute
        {
            public override void OnActionExecuted(HttpActionExecutedContext context)
            {
                //context.ActionContext
                var actionName = ((System.Web.Http.Controllers.ReflectedHttpActionDescriptor)context.ActionContext.ActionDescriptor).ActionName;
                var controllerName = context.ActionContext.ControllerContext.ControllerDescriptor.ControllerName;
                base.OnActionExecuted(context);
            }
        }
    
        public class CustomExceptionFilter : ExceptionFilterAttribute
        {
            public override void OnException(HttpActionExecutedContext actionExecutedContext)
            {
                //context.ActionContext
                var actionName = ((System.Web.Http.Controllers.ReflectedHttpActionDescriptor)actionExecutedContext.ActionContext.ActionDescriptor).ActionName;
                var controllerName = actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName;
            }
        }
    

    【讨论】:

      【解决方案2】:

      您关于使用 ActionFilter 的决定是好的。事情是决定在哪里放置审计调用,在调用(OnActionExecuting)之前或之后(OnActionExecuted)动作名称被调用。这是您必须根据需要做出的技术决定。

      过滤器类:

          public class AuditFilter : ActionFilterAttribute
          {
              public override void OnActionExecuting(HttpActionContext actionContext)
              {
                  var controllerName = actionContext.ControllerContext.ControllerDescriptor.ControllerName;
                  var actionName = actionContext.ActionDescriptor.ActionName;
                  var auditRepository = SvcLocator.GetInstance<IAuditRepository>();
                  auditRepository.SaveAudit(controllerName, actionName);
              }
      
              public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
              {
                  var controllerName = actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerName;
                  var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
                  var auditRepository = SvcLocator.GetInstance<IAuditRepository>();
                  auditRepository.SaveAudit(controllerName, actionName);
              }
          }
      

      考虑创建一个用于创建审计对象的新组件。在过滤器类中保持干净的代码。 更重要的是,你可以重构代码,因为两个方法中的代码是相似的。

      控制器:

       [AuditFilter]
       public class ChatroomController : ApiController
       {...
      

      新组件:

        public class AuditRepository : IAuditRepository
        {
            public void SaveAudit(string controllerName, string actionName)
            {
                var auditEntity = new AuditEntity()
                  {
                      TableName = "Customer",
                      ManuId = "Shopping",
                      ControllerId = controllerName,
                      ActionId = actionName
                  };
      
                  //Save into database here
              }
          }
      

      注意:

      • 由于您需要对所有控制器的所有操作进行审核,因此必须将属性放在控制器级别,以便所有操作都执行过滤器
      • 在这里运行 base.OnActionExecuted 没有任何意义,因为网络框架中没有默认实现。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多