IHttpHandler GetHttpHandler不会触发的情况

时间:2012-12-18 15:47:52

标签: c# .net asp.net-mvc web-applications ihttphandler

我有一个项目需要更改MVC的图像http请求的默认路由行为。

例如,这个来自RouteConfig.cs的样本

Route ImagesRoute = new Route("{controller}/{folderName}/{fileName}", new ImageRouteHandler());
string regexWindowsFilePattern = @"^([^\x00-\x1f\\?/%*:|" + "\"" + @"<>]+)\.(?:jpeg|jpg|tiff|gif|png)";

ImagesRoute.Constraints = new RouteValueDictionary { { "fileName", regexWindowsFilePattern } };
routes.Add(ImagesRoute);

应重新路由

http://localhost/home/contents/image.jpg

到磁盘上的路径(c:\ cache \ [folderName] [fileName])。在我的情况下,“重新路由”只是根据请求编写正确的http响应。在一个项目中(让我们称之为“测试”项目),此代码触发正常行为:ImageRouteHandler类的GetHttpHandler方法被命中并且图像出现在浏览器中,但是在其他项目中使用相同的代码为RouteConfig.cs和ImageRouteHandler插入GetHttpHandler不会触发导致404 NOT FOUND http错误。这个其他项目(“目标”项目)具有几乎相同的配置(我已经检查了相关的差异)并且已经在同一个IIS Express服务器上运行。创建新项目并填充目标和测试项目的内容会导致正常行为(即图像显示在浏览器中)。 关于解决方案可能是什么的任何线索?

update_1:
我忘了提到这个动作并没有刻意使用。我有一个html文件,我必须包含在部分视图中,它将呈现html文件正文。我无法控制如何创建此文件,但我有一个已定义的结构:名称为[htmlFileName]的html文件和名称为[htmlFileName] .files的资源文件夹名称。当我请求特定的URL(比如localhost / [Controller] / [Action])时,对HTML标记中的资源的引用会导致URL不正确(http:// localhost / [Controller] / [folderName] / [fileName])所以我需要重写这些URL,以便更好地回答浏览器的http图像请求。这就是为什么我认为需要这个自定义处理程序。

using System;
using System.Net;
using System.Web;
using System.IO;
using System.Web.Routing;

namespace MyProject.WebUI.Interface.Utility
{
    public class ImageRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            string fileName = requestContext.RouteData.Values["fileName"] as string;
            string folderName = requestContext.RouteData.Values["folderName"] as string;

            if (string.IsNullOrEmpty(fileName))
            {
                // return a 404 NOT FOUND HttpHandler here
                requestContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
            }
            else
            {
                requestContext.HttpContext.Response.Clear();

                if (requestContext.HttpContext.Request.Url != null)
                {
                    requestContext.HttpContext.Response.ContentType =
                        GetContentType(requestContext.HttpContext.Request.Url.ToString());
                }
                else
                {
                    requestContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    requestContext.HttpContext.Response.End();
                }

                // find physical path to image here.  
                string filepath = @"c:\Cache" + @"\" + folderName + @"\" + fileName;

                /*If file exists send the response, otherwise set HTTP 404 NOT FOUND status code for response.*/
                if (File.Exists(filepath))
                {
                    requestContext.HttpContext.Response.WriteFile(filepath);
                    requestContext.HttpContext.Response.End();
                }
                else
                {
                    requestContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    requestContext.HttpContext.Response.End();
                }


            }
            return null;
        }


        private static string GetContentType(String path)
        {
            switch (Path.GetExtension(path))
            {
                case ".bmp": return "Image/bmp";
                case ".gif": return "Image/gif";
                case ".jpg": return "Image/jpeg";
                case ".jpeg": return "Image/jpg";
                case ".png": return "Image/png";
                default: break;
            }
            return "";
        }
    }
}

1 个答案:

答案 0 :(得分:3)

似乎在一个项目中,Web.config中有“modules”元素

<modules runAllManagedModulesForAllRequests="true" />

允许路由模块与图像请求一起正常工作。它默认放在Web.config中,由于某种原因,在另一个项目中没有这样的xml元素。虽然这是一个问题的解决方案,但我找到了一个更好的解决方案:

<modules>
  <remove name="UrlRoutingModule-4.0" />
  <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>

这为任何类型的请求只启用一个(而不是全部)托管模块。将这些xml元素添加到Web.config后,ImageRouteHandler的GetHttpHandler会按预期命中。