Reputation: 82156
Question:
This is my RegisterRoutes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add("ImagesRoute", new Route("graphics/{*filename}", new HttpRuntime.Routing.ImageRouteHandler()));
// insert_dateti
routes.MapRoute(
"Default", // Routenname
"{controller}/{action}/{id}", // URL mit Parametern
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameterstandardwerte
//new { controller = "Home", action = "Splash", id = UrlParameter.Optional } // Parameterstandardwerte
//new { controller = "Folders", action = "Content", id = UrlParameter.Optional } // Parameterstandardwerte
);
} // End Sub RegisterRoutes
And this is my route handler
using System;
using System.IO;
using System.Web;
using System.Linq;
using System.Web.UI;
using System.Web.Routing;
using System.Web.Compilation;
using System.Collections.Generic;
namespace HttpRuntime.Routing
{
public class ImageRouteHandler : IRouteHandler
{
public string MapRemoteLocation(string strPath)
{
if (string.IsNullOrEmpty(strPath))
return "";
string strBaseURL = "http://madskristensen.net/themes/standard/";
return strBaseURL + strPath;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string filename = requestContext.RouteData.Values["filename"] as string;
if (string.IsNullOrEmpty(filename))
{
// return a 404 HttpHandler here
requestContext.HttpContext.Response.StatusCode = 404;
requestContext.HttpContext.Response.End();
return null;
} // End if (string.IsNullOrEmpty(filename))
else
{
requestContext.HttpContext.Response.Clear();
requestContext.HttpContext.Response.ContentType = GetContentType(filename);
requestContext.HttpContext.Response.Redirect(MapRemoteLocation(filename));
// find physical path to image here.
//string filepath = requestContext.HttpContext.Server.MapPath("~/test.jpg");
// string stPath = requestContext.HttpContext.Request.Url.AbsolutePath;
//requestContext.HttpContext.Response.WriteFile(filepath);
//requestContext.HttpContext.Response.End();
} // End Else of if (string.IsNullOrEmpty(filename))
return null;
} // End Function GetHttpHandler
public static void MsgBox(object obj)
{
if (obj != null)
System.Windows.Forms.MessageBox.Show(obj.ToString());
else
System.Windows.Forms.MessageBox.Show("obj is NULL");
} // End Sub MsgBox
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 ".png": return "Image/png";
default: break;
} // End switch (Path.GetExtension(path))
return "";
} // End Function GetContentType
} // End Class ImageRouteHandler : IRouteHandler
} // End Namespace HttpRuntime.Routing
The goal of this is, that when i have this in /Home/Index.cshtml
<img src="graphics/mads2011.png?v=123" title="Compose E-Mail" alt="Compose E-Mail" />
it downloads the picture from a remote host.
It works fine as long as I have
routes.Add("ImagesRoute", new Route("graphics/{filename}", new HttpRuntime.Routing.ImageRouteHandler()));
But when I change it to
routes.Add("ImagesRoute", new Route("graphics/{*filename}", new HttpRuntime.Routing.ImageRouteHandler()));
in order to allow subfolders, then it redirects every url action to /graphics.
e.g. when I have
$(function () {
$("#divJsTreeDemo").jstree({
"json_data" : {
"ajax" : {
"url": "@Url.Action("GetNodesJson", "Home")"
//"url": "@Url.Action("GetTreeData", "Home")"
,"async" : true
in Home/Index.cshtml
the URL for the AJAX call on the resulting HTML page becomes
"url": "/graphics?action=GetNodesJson&controller=Home"
Why is this ? And how can I fix this ? If I move my ImagesRoute to the bottom, the JavaScript routes correctly, but then I can get no more remote images, because they are routed to controller "graphics", which doesn't exists --> Exception no such view...
Upvotes: 1
Views: 3297
Reputation: 10924
When building links from routes, your ImagesRoute
using {*filename}
will satisfy all conditions, so that route will always be used to build links if it precedes your Default
route in your routes table. However, when processing requests, it works as expected, because the ImagesRoute route will only be satisfied by requests starting http://mysite.com/graphics/...
In order to fix this, you need to move the ImagesRoutes below the default route, and you then need to add a RouteConstraint
to the Default route, so that any request starting with graphics
will fail the Default route.
Change your Default route as follows:
routes.MapRoute(
"Default", // Routenname
"{controller}/{action}/{id}", // URL mit Parametern
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // defaults
new { controller = @"^(?!graphics).+" } // constraint
);
Upvotes: 2