我有一个项目需要更改 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 "";
}
}
}