我有一个项目需要更改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 "";
}
}
}
答案 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会按预期命中。