是否可以使用ASP.Net路由(而不是MVC)来服务静态文件?
假设我想路由
http://domain.tld/static/picture.jpg
至
http://domain.tld/a/b/c/picture.jpg
我想要动态地做这件事,重写的URL是动态计算的。我不能一劳永逸地设置静态路由。
无论如何,我可以像这样创建一条路由:
routes.Add(
"StaticRoute", new Route("static/{file}", new FileRouteHandler())
);
在FileRouteHandler.ProcessRequest
方法中,我可以重写从/static/picture.jpg
到/a/b/c/picture.jpg
的路径。然后,我想为静态文件创建一个处理程序。ASP.NET使用StaticFileHandler
来实现此目的。不幸的是,这个类是内部的。我尝试使用反射来创建处理程序,它实际上是有效的:
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);
但是使用内部类型似乎不是正确的解决方案。另一种选择是实现我自己的StaticFileHandler
,但正确地这样做(支持范围和etags之类的HTTP内容)并不是一件容易的事情。
我应该如何在ASP.NET中路由静态文件?
发布于 2010-06-25 01:02:51
在深入研究这个问题几个小时后,我发现只需添加忽略规则就可以处理您的静态文件。
在RegisterRoutes(RouteCollection路由)中,添加以下忽略规则:
routes.IgnoreRoute("{file}.js");
routes.IgnoreRoute("{file}.html");
发布于 2010-10-17 14:26:24
我也遇到过类似的问题。我最终使用了HttpContext.RewritePath
public class MyApplication : HttpApplication
{
private readonly Regex r = new Regex("^/static/(.*)$", RegexOptions.IgnoreCase);
public override void Init()
{
BeginRequest += OnBeginRequest;
}
protected void OnBeginRequest(object sender, EventArgs e)
{
var match = r.Match(Request.Url.AbsolutePath);
if (match.Success)
{
var fileName = match.Groups[1].Value;
Context.RewritePath(string.Format("/a/b/c/{0}", fileName));
}
}
}
发布于 2009-08-24 09:04:50
我想出了一个替代使用内部StaticFileHandler
的方法。在IRouteHandler
中,我调用HttpServerUtility.Transfer
public class FileRouteHandler : IRouteHandler {
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
String fileName = (String) requestContext.RouteData.Values["file"];
// Contrived example of mapping.
String routedPath = String.Format("/a/b/c/{0}", fileName);
HttpContext.Current.Server.Transfer(routedPath);
return null; // Never reached.
}
}
这是个黑客攻击。IRouteHandler
应该返回一个IHttpHandler
,而不是中止和传输当前请求。然而,它确实达到了我想要的效果。
使用内部StaticFileHandler
也有点麻烦,因为我需要反射来访问它,但至少有一些documentation on StaticFileHandler
on MSDN使它成为一个稍微“正式”的类。不幸的是,我不认为在部分信任环境中反映内部类是可能的。
我将坚持使用StaticFileHandler
,因为我认为在可预见的将来它不会从ASP.NET中删除。
https://stackoverflow.com/questions/1149750
复制相似问题