【问题标题】:ASP.NET MVC Request filtersASP.NET MVC 请求过滤器
【发布时间】:2011-08-05 02:50:19
【问题描述】:

ASP.NET MVC 是否不支持某种 RequestFilters - 在控制器和动作实例化之前每个请求执行一次的过滤器?

【问题讨论】:

  • 动作过滤器在执行动作方法之前执行,但在控制器实例化之前不执行

标签: asp.net-mvc


【解决方案1】:

您可以创建自己的路由处理程序,它可能在管道中足够早地实现您的目标。

public class MyRoutingHandler : IRouteHandler
{
    protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new InterceptingMvcHandler(requestContext);
    }

    IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
    {
        return GetHttpHandler(requestContext);
    }

}

以及对应的mvc处理程序:

public class InterceptingMvcHandler : MvcHandler
{
    public InterceptingMvcHandler(RequestContext requestContext) : base(requestContext)
    {
    }

    protected override IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state)
    {
        httpContext.Response.Write("<h2>BeginProcessRequest</h2>");
        return base.BeginProcessRequest(httpContext, callback, state);
    }

    protected override void EndProcessRequest(IAsyncResult asyncResult)
    {
        var context = RequestContext.HttpContext;
        base.EndProcessRequest(asyncResult);
        if (context != null)
        {
            context.Response.Write("<h2>EndProcessRequest</h2>");
        }
    }
}

然后您可以在路由注册中注册 mvc 处理程序。

【讨论】:

    【解决方案2】:

    这里有一个例子;

    public class CompressFilter : ActionFilterAttribute {
    
        public override void OnActionExecuting(ActionExecutingContext filterContext) {
    
            HttpRequestBase request = filterContext.HttpContext.Request;
    
            string acceptEncoding = request.Headers["Accept-Encoding"];
    
            if (string.IsNullOrEmpty(acceptEncoding)) return;
    
            acceptEncoding = acceptEncoding.ToUpperInvariant();
    
            HttpResponseBase response = filterContext.HttpContext.Response;
    
            if (acceptEncoding.Contains("GZIP")) {
    
                response.AppendHeader("Content-encoding", "gzip");
                response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
    
            } else if (acceptEncoding.Contains("DEFLATE")) {
    
                response.AppendHeader("Content-encoding", "deflate");
                response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
            }
    
        }
    
    }
    

    您创建的,您可以在每个操作、每个控制器甚至全局项目基础上使用它;

        public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
    
            filters.Add(new CompressFilter());
    
        }
    

    【讨论】:

      【解决方案3】:

      在 ASP.NET MVC 中有action filters 允许您在请求执行的不同阶段运行一些自定义代码。

      1. 执行操作之前
      2. 动作执行后
      3. 在结果呈现之前
      4. 渲染结果后

      根据您愿意执行的代码和您想要执行的功能类型,可能有其他方法可以插入到框架中。

      【讨论】:

      • 正如我所说,我需要在控制器(主要是它的依赖项)实例化之前实现一些逻辑
      • @Idsa,您能否更具体地了解一下您要实施的 逻辑 吗?这样我们或许可以为您提供更合适的解决方案。
      • 我需要在控制器实例化之前确定当前请求的本地化语言,因为我的本地化服务是根据当前语言注册的:Bind.To.When(r => CurrentLanguage.Language = = Language.English) (ninject 语法)。因此,如果未设置 CurrentLanguage,则不会实例化控制器。我可以在 Global.asax Application_OnRequest 中执行这个逻辑,但我认为可能有更自然的 ASP.NET MVC 方式
      • 假设我想在每个请求中检查 cookie 的值 - 那么我应该使用 Application_BeginRequest (global.asax) 还是应该使用 Action Filter?
      猜你喜欢
      • 1970-01-01
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多