从MVC routehandler返回404

时间:2012-12-11 13:30:32

标签: c# asp.net-mvc-3 routes httphandler blacklist

我有一个IP列表,它继续抓取我们的实时站点,当它们使用某些没有参数的URL时(由于MVC路由)会抛出异常。我想阻止这些IP地址并在它们被拾取后立即返回404找不到的页面,但我不想在IIS中这样做,因为我想在我们的应用程序中记录遭遇。

我编写了一个catch-all类型的routehandler,它使用自定义MvcHandler来检查列表并修改响应:

public class ApplicationRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        BlacklistedIPAddressHandler handler = new BlacklistedIPAddressHandler(Cache.WebsiteCache.GetBlacklistedIPList(), requestContext);

        return handler;
    }
}

public class BlacklistedIPAddressHandler : MvcHandler
{
    List<IPBlacklistModel> blacklist;

    public BlacklistedIPAddressHandler(List<IPBlacklistModel> Blacklist, RequestContext requestContext) : base(requestContext)
    {
        blacklist = Blacklist;
    }

    protected override IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state)
    {
        var ip = httpContext.Request.UserHostAddress;

        if (blacklist != null &&
            blacklist.Where(x => x.IP_ADDRESS.Contains(ip)).Count() > 0)
        {

            httpContext.Response.ClearHeaders();
            httpContext.Response.Clear();

            httpContext.Response.StatusCode = 404;
            httpContext.Response.SuppressContent = true;
            httpContext.Response.End();
        }

        return base.BeginProcessRequest(httpContext, callback, state);
    }
}

然后按如下方式实施:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            new { controller = @"[^\.]*" }
        ).RouteHandler = new Helpers.Routing.ApplicationRouteHandler();
    }

当我这样做时,我一直收到服务器无法追加标头后发送HTTP标头错误。任何人都知道为什么?

1 个答案:

答案 0 :(得分:2)

我想您应该从处理程序中删除httpContext.Response.End();语句 - 因为请求被传递以进行进一步处理,现在不应该终止它。

来自MSDN

HttpResponse.End方法说明:

  

将所有当前缓冲的输出发送到客户端,停止执行   页面,并引发EndRequest事件。