ASP.Net Web API - 如何取消注册自定义操作过滤器?

时间:2016-12-28 13:13:42

标签: c# asp.net api asp.net-web-api filter

我为Web API 2开发了自定义操作过滤器 - LogActionWebApiFilter

namespace Utility.Logger.WebApi.RequestResponse.Attributes
{
    /// <summary>
    /// Log action web API action filter
    /// </summary>
    internal class LogActionWebApiFilter : ActionFilterAttribute
    {
        #region Private Fields

        /// <summary>
        /// The current identifier
        /// </summary>
        private static Guid currentId;

        /// <summary>
        /// The request start time
        /// </summary>
        private static DateTime requestStartTime;

        /// <summary>
        /// The logger
        /// </summary>
        private IEventLogger logger;

        #endregion Private Fields

        #region Public Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="LogActionWebApiFilter"/> class.
        /// </summary>
        /// <param name="logger">The logger.</param>
        public LogActionWebApiFilter(IEventLogger logger)
        {
            this.logger = logger;
        }

        #endregion Public Constructors

        #region Public overrided Methods

        /// <summary>
        /// Occurs after the action method is invoked.
        /// </summary>
        /// <param name="actionExecutedContext">The action executed context.</param>
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.ActionContext.ActionDescriptor.GetCustomAttributes<NoLogWebApiFilter>().Any())
            {
                return;
            }

            // Some business logic

            this.logger.DebugFormat("API Call of {0}()", actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
        }

        /// <summary>
        /// Occurs before the action method is invoked.
        /// </summary>
        /// <param name="actionContext">The action context.</param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ActionDescriptor.GetCustomAttributes<NoLogWebApiFilter>().Any())
            {
                return;
            }

            // Some business logic
        }

        #endregion Public overrided Methods
    }
}

现在,我希望在应用程序启动后根据标志注册/取消注册此自定义操作过滤器运行时。

这是我的过滤器注册码:

public void StartLogging()
{
    var existingFilter
       = System.Web.Http.GlobalConfiguration.Configuration.Filters.FirstOrDefault(
                   f =>
                       f.Instance.GetType().ToString().Equals(typeof(LogActionWebApiFilter).ToString()
                       ));

    if (existingFilter == null)
    {
        System.Web.Http.GlobalConfiguration.Configuration.Filters.Add(new LogActionWebApiFilter(this.logger));
    }
}

这是我的过滤器注销代码:

public void StopLogging()
{
    var existingFilter
        = System.Web.Http.GlobalConfiguration.Configuration.Filters.FirstOrDefault(
                    f =>
                        f.Instance.GetType().ToString().Equals(typeof(LogActionWebApiFilter).ToString()
                        ));

    if (existingFilter != null)
    {
        System.Web.Http.GlobalConfiguration.Configuration.Filters.Remove(existingFilter.Instance);
        existingFilter = null;
    }
}

问题: -

  • 在每个Application_BeginRequest() - 事件中,我检查标志(有一些业务逻辑),并根据标志的值我从上述两种方法中调用相应的方法。
  • 但是,上述任何一种方法都不起作用。
  • 偶数过滤器已添加到System.Web.Http.GlobalConfiguration.Configuration.Filters,但OnActionExecuting() / OnActionExecuted()中的任何一个都未被调用。

请指导我,我在这里做错了什么。

提前致谢, Balaguru。

2 个答案:

答案 0 :(得分:0)

无法在Application_BeginRequest()事件中控制动作过滤器。动作过滤器是全局过滤器,只能在Application_Start()中注册。

我建议你可以通过配置文件添加或删除过滤器。

<configSections>
<section name="filters" type="ConfigurableFilters.FiltersSettings,  AssemblyName "/> 
</configSections>

<filters>
  <add type="ConfigurableFilters.BarFilter, AssemblyName" />
  <add type="ConfigurableFilters.FooFilter, AssemblyName" />
</filters>

在这种情况下,您需要一个ConfigurationElement。

 Public class FilterAction : ConfigurationElement
{
[ConfigurationProperty("type", IsRequired = true, IsKey = true)]
public string Type 
{
    get { return base["type"] as string; }
    set { base["type"] = value; }
}
}

还有一个ConfigurationElementCollection。

    public class FilterActionCollection : ConfigurationElementCollection
    {       
       protected override ConfigurationElement CreateNewElement()
       {  return new FilterAction();}

    protected override object GetElementKey(ConfigurationElement element)
       {  return ((FilterAction) element).Type;}
   }

还有一个ConfigurationSection。

    public class FiltersSettings : ConfigurationSection
    {
      public static FiltersSettings Settings
       {
          get {
             var section = ConfigurationManager.GetSection("filters")
                      as FiltersSettings;
             return section ?? new FiltersSettings();                
              }
        }

     [ConfigurationProperty("", IsDefaultCollection = true)]
     public FilterActionCollection Filters
       {
        get { return base[_filtersProperty] as FilterActionCollection; }
        set { base[_filtersProperty] = value; }
       }

    private readonly ConfigurationProperty _filtersProperty = 
    new ConfigurationProperty(
        null, typeof (FilterActionCollection), null, 
        ConfigurationPropertyOptions.IsDefaultCollection);
  }

应用已配置过滤器的一种方法是在应用程序启动期间使用以下代码:

    var filters = FiltersSettings.Settings.Filters;
    foreach (var filter in filters.Cast<FilterAction>())
     {
        var filterType = Type.GetType(filter.Type);
       GlobalFilters.Filters.Add(Activator.CreateInstance(filterType));
     }

答案 1 :(得分:0)

这里最简单的答案是将一个切换值添加到/* Smartphones (portrait and landscape) ----------- */ @media only screen and (min-device-width : 320px) and (max-device-width : 480px) { /* Styles */ } /* Smartphones (landscape) ----------- */ @media only screen and (min-width : 321px) { /* Styles */ } /* Smartphones (portrait) ----------- */ @media only screen and (max-width : 320px) { /* Styles */ } /* iPads (portrait and landscape) ----------- */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) { /* Styles */ } /* iPads (landscape) ----------- */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) { /* Styles */ } /* iPads (portrait) ----------- */ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) { /* Styles */ } /********** iPad 3 **********/ @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio : 2) { /* Styles */ } @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio : 2) { /* Styles */ } /* Desktops and laptops ----------- */ @media only screen and (min-width : 1224px) { /* Styles */ } /* Large screens ----------- */ @media only screen and (min-width : 1824px) { /* Styles */ } /* iPhone 4 ----------- */ @media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio : 2) { /* Styles */ } @media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio : 2) { /* Styles */ } /* iPhone 5 ----------- */ @media only screen and (min-device-width: 320px) and (max-device-height: 568px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } @media only screen and (min-device-width: 320px) and (max-device-height: 568px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } /* iPhone 6 ----------- */ @media only screen and (min-device-width: 375px) and (max-device-height: 667px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } @media only screen and (min-device-width: 375px) and (max-device-height: 667px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } /* iPhone 6+ ----------- */ @media only screen and (min-device-width: 414px) and (max-device-height: 736px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } @media only screen and (min-device-width: 414px) and (max-device-height: 736px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } /* Samsung Galaxy S3 ----------- */ @media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } @media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){ /* Styles */ } /* Samsung Galaxy S4 ----------- */ @media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 3){ /* Styles */ } @media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 3){ /* Styles */ } /* Samsung Galaxy S5 ----------- */ @media only screen and (min-device-width: 360px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 3){ /* Styles */ } @media only screen and (min-device-width: 360px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 3){ /* Styles */ }并在您的日志记录代码中查询。

Request.Properties

在您的记录器中:

public void StartLogging()
{
    // Check the value does not already exist etc. and either add or modify.
    if (actionContext.Request.Properties.ContainsKey("ShouldLog")) {
        actionContext.Request.Properties["ShouldLog"] = true;
    }
    else {
        actionContext.Request.Properties.Add("ShouldLog", true);
    }
}