I have a project that requires changes in MVC's default routing behavior for image http requests.
For example, this sample from 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);
should reroute
http://localhost/home/contents/image.jpg
to path on disk (c:\cache\[folderName][fileName]). The "rerouting" in my case is just writing the correct http response based on request. In one project (lets call it the "Test" project) this code triggers normal behavior: the GetHttpHandler method of ImageRouteHandler class gets hit and the image appears in browser, however in other project with identical code for RouteConfig.cs and ImageRouteHandler inserted GetHttpHandler simply does not fire which results in 404 NOT FOUND http error. This other project (the "destination" project) has almost the same configuration (I have checked the relevant differences) and have been run on the same IIS express server. Creating new project and populating in with contents of destination and test project results in normal behavior (i.e. the image is displayed in browser). Any clue on what the solution might be?
update_1:
I forgot to mention that the action is not used deliberately. I have an html file that I must include into partial view which will render html file body. I don't have control over how this file is created but I have a defined structure: html file with name [htmlFileName] and a resource folder name with name [htmlFileName].files. When I request a specific URL (say localhost/[Controller]/[Action]) the references to resources in HTML markup result in incorrect URLs (http:// localhost/[Controller]/[folderName]/[fileName]) so I need to rewrite these URLs so that the browser's http image requests are prorerly answered. Thats why I think this custom handler is needed.
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 "";
}
}
}