ASP.NET - Handle HTTP 404

在Global.asax.cs中添加如下方法:

protected void Application_EndRequest()
{
    if (Context.Response.StatusCode == 404) {
        var rd = new RouteData();
        rd.Values["action"] = "PageNotFound";
        IController c = new HomeController();
        c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
    }
}

HomeController中增加PageNotFound()处理截获的请求(注:对于GetManifestResourceStream资源名称是区分大小写的)

public void HandleStaticRequest()
{
    var resourceUrl = Request.Url.AbsolutePath.TrimStart('/').Replace('/', '.');
    var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceUrl);
    if (stream != null) {
        Response.ContentType = "image/jpeg";    // <-- apply corresponding mime type

        stream.CopyTo(Response.OutputStream);
    }
    else {
        Response.StatusCode = 404;
        Response.Write(string.Format("Resource not found: {0}", Request.Url.AbsoluteUri));
    }
}

public void PageNotFound()
{
    Response.Clear();
    HandleStaticRequest();
}

为了路由到静态文件,需要在路由表的配置中设置RouteExistingFiles = true

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.RouteExistingFiles = true;
    ……
}

另外还需要在web.config中增加对静态文件的处理方法:

<system.webServer>
  <handlers>
    <add name="JpgFileHandler" path="*.jpg" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>