可以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
,但这样做正确(如范围和ETag的支持HTTP的东西)是不平凡的。
我应该如何看待的静态文件路由在ASP.NET?
通过这个问题,几个小时后挖,我发现,简单地增加无视规则,将让您的静态文件服务。
在的RegisterRoutes(RouteCollection路线),添加以下无视规则:
routes.IgnoreRoute("{file}.js");
routes.IgnoreRoute("{file}.html");
为什么不使用IIS来做到这一点? 你可以只创建重定向规则,使其指向从第一路线的任何请求第二个请求之前,甚至会到你的应用程序。 正因为如此,这将是一个重定向请求更快的方法。
假设你已经IIS7 +,你这样做......
<rule name="Redirect Static Images" stopProcessing="true">
<match url="^static/?(.*)$" />
<action type="Redirect" url="/a/b/c/{R:1}" redirectType="Permanent" />
</rule>
或者 ,如果你不需要重定向,由@ ni5ni6的建议:
<rule name="Rewrite Static Images" stopProcessing="true">
<match url="^static/?(.*)$" />
<action type="Rewrite" url="/a/b/c/{R:1}" />
</rule>
编辑2015-06-17为@RyanDawkins:
如果你想知道在哪里重写规则去,这里是一个映射在它的位置web.config
文件。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- rules go below -->
<rule name="Redirect Static Images" stopProcessing="true">
<match url="^static/?(.*)$" />
<action type="Redirect" url="/a/b/c/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
我也有过类似的问题。 我最终使用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));
}
}
}
我想出了一个替代使用内部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
也有些黑客攻击,因为我需要反射来访问它,但至少有一些关于文件StaticFileHandler
MSDN上使其成为一个略微更“官方”类。 不幸的是,我不认为这是可能的,以反映在部分信任环境中的内部类。
我会坚持使用StaticFileHandler
,因为我不认为它会从ASP.NET在可预见的将来得到去除做。
您需要添加TransferRequestHandler处理您的静态files.Please看到以下的答案https://stackoverflow.com/a/21724783/22858