Can ASP.Net routing (not MVC) be used to serve static files?
Say I want to route
http://domain.tld/static/picture.jpg
to
http://domain.tld/a/b/c/picture.jpg
and I want to do it dynamically in the sense that the rewritten URL is computed on the fly. I cannot set up a static route once and for all.
Anyway, I can create a route like this:
routes.Add(
"StaticRoute", new Route("static/{file}", new FileRouteHandler())
);
In the FileRouteHandler.ProcessRequest
method I can rewrite the path from /static/picture.jpg
to /a/b/c/picture.jpg
. I then want to create a handler for static files. ASP.NET uses the StaticFileHandler
for this purpose. Unfortunately, this class is internal. I have tried to create the handler using reflection and it actually works:
Assembly assembly = Assembly.GetAssembly(typeof(IHttpHandler));
Type staticFileHandlerType = assembly.GetType("System.Web.StaticFileHandler");
ConstructorInfo constructorInfo = staticFileHandlerType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
return (IHttpHandler) constructorInfo.Invoke(null);
But using internal types doesn't seem to be the proper solution. Another option is to implement my own StaticFileHandler
, but doing so properly (supporting HTTP stuff like ranges and etags) is non-trivial.
How should I approach routing of static files in ASP.NET?
You need to add TransferRequestHandler for handling your static files.Please see following answer https://stackoverflow.com/a/21724783/22858
After digging through this problem for a few hours, I found that simply adding ignore rules will get your static files served.
In RegisterRoutes(RouteCollection routes), add the following ignore rules:
Why not use IIS to do this? You could just create redirect rule to point any requests from the first route to the second one before the request even gets to your application. Because of this, it would be a quicker method for redirecting requests.
Assuming you have IIS7+, you do something like...
Or, if you don't need to redirect, as suggested by @ni5ni6:
Edit 2015-06-17 for @RyanDawkins:
And if you're wondering where the rewrite rule goes, here is a map of its location in the
web.config
file.I've had a similar problem. I ended up using HttpContext.RewritePath:
I came up with an alternative to using the internal
StaticFileHandler
. In theIRouteHandler
I callHttpServerUtility.Transfer
:This is a hack. The
IRouteHandler
is supposed to return anIHttpHandler
and not abort and transfer the current request. However, it does actually achieve what I want.Using the internal
StaticFileHandler
is also somewhat a hack since I need reflection to get access to it, but at least there is some documentation onStaticFileHandler
on MSDN making it a slightly more "official" class. Unfortunately I don't think it is possible to reflect on internal classes in a partial trust environment.I will stick to using
StaticFileHandler
as I don't think it will get removed from ASP.NET in the foreseeable future.