2009-07-19 12 views
61

スタティックファイルの配信にASP.Netルーティング(MVCではなく)を使用できますか?ASP.NETルーティングを使用して静的ファイルを配信する

は私がルート

http://domain.tld/static/picture.jpg 

http://domain.tld/a/b/c/picture.jpg 

にしたいと私は書き換えられたURLは、その場で計算されるという意味で動的にそれをしたいと言います。私は静的経路を一度に設定することはできません。私は/static/picture.jpgから/a/b/c/picture.jpgへのパスを書き換えることができ

routes.Add(
    "StaticRoute", new Route("static/{file}", new FileRouteHandler()) 
); 

FileRouteHandler.ProcessRequest方法で:

とにかく、私はこのようなルートを作成することができます。私は静的ファイル用のハンドラを作成したいと思います。 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を実装することですが、これを正しく行うと(rangeやetagsのようなHTTPをサポートしています)、簡単です。

ASP.NETで静的ファイルのルーティングにどのようにアプローチする必要がありますか?

答えて

37

この問題を数時間掘り下げた後、無視ルールを追加するだけで静的ファイルが提供されることがわかりました。 RegisterRoutesで

(RouteCollectionルート)、無視する次のルールを追加します。

routes.IgnoreRoute("{file}.js"); 
routes.IgnoreRoute("{file}.html"); 
+0

私の場合は動作しますが、領域のビューフォルダでJSファイルを解析できません。修正するために、代わりに/Areas/MyArea/ClientScripts/foo.jsのような領域のベースフォルダ内の別のフォルダを使用します – eka808

+20

何とか私はパズルの一部を見逃しているようです...あなたの静的ファイルへのルートを無視すると、 '/ static'から'/a/b/c'(OPが要求したもの)へのルーティングにどのように役立ちますか?あなたはあなたの答えにもっと光を当ててください、私は本当にこの解決策を理解したいと思います。 – Oliver

+17

Oliverと合意すると、これはOPには答えず、解決策として受け入れられません。 – dhochee

48

なぜIISを使用しないのですか?要求がアプリケーションに到達する前に、最初のルートから2番目のルートへのリクエストを指すリダイレクトルールを作成できます。このため、要求をリダイレクトするためのより迅速な方法になります。

の@ ni5ni6により示唆されるようにあなたは、リダイレクトする必要がない場合は、何かのような...

<rule name="Redirect Static Images" stopProcessing="true"> 
    <match url="^static/?(.*)$" /> 
    <action type="Redirect" url="https://stackoverflow.com/a/b/c/{R:1}" redirectType="Permanent" /> 
</rule> 

またはを行い、あなたはIIS7 +を持っていると仮定すると:

<rule name="Rewrite Static Images" stopProcessing="true"> 
    <match url="^static/?(.*)$" /> 
    <action type="Rewrite" url="https://stackoverflow.com/a/b/c/{R:1}" /> 
</rule> 

@RyanDawkinsの2015-06-17を編集する

書き換えルールがどこに行くのか不思議なら、ここをクリックしてください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="https://stackoverflow.com/a/b/c/{R:1}" redirectType="Permanent" /> 
     </rule> 
     </rules> 
    </rewrite> 
    </system.webServer> 
</configuration> 
+0

を参照してくださいfiles.Please。それをパイプラインに移動し、IISワーカープロセスがリダイレクトを処理できるようにすることは、実際にランタイム経由でルートを処理するサイクルよりも効率的です。サーバ上の解約量がほぼ同じであっても、ルートを使用していないルート(言い訳は意図している)に行き、アプリケーション自体の外にリダイレクトを保持します。 –

+0

質問の最初のバージョンからはっきりしなかったことは、書き換えられたURLがオンザフライで計算されていることです(私はここでのパフォーマンスについて心配していません)。私はそれを明確にするために質問を更新しました。とにかく、お返事いただきありがとうございます。 –

+0

(私の前のコメントを削除し、短縮されていないURLでそれを再追加しました)。 Martin、パフォーマンスの問題はさておき、アプリケーションでこのURLを処理したいのですが、外部で処理する方がよいでしょうか?私はあなたがこれを処理するコントローラアクションを作成することができたと思いますが、ここであなたが見てみることができるものです: - http://geekswithblogs.net/sankarsan/archive/2009/01/18/developing-custom-routehandler.aspx –

5

私は内部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("https://stackoverflow.com/a/b/c/{0}", fileName); 
    HttpContext.Current.Server.Transfer(routedPath); 
    return null; // Never reached. 
    } 

} 

これはハックです。 IRouteHandlerは、IHttpHandlerを返し、現在の要求を中止して転送しないことになっています。しかし、それは実際に私が望むものを達成します。

内部のStaticFileHandlerを使用すると、私はそれにアクセスするためにリフレクションが必要なので少しハックしますが、少なくとも少しは「公式」クラスになるdocumentation on StaticFileHandler on MSDNがあります。残念ながら私は部分的な信頼環境で内部クラスを反映することは可能ではないと思います。

近い将来にASP.NETから削除されるとは思わないので、私はStaticFileHandlerを使用することに固執します。

9

私は同様の問題を持っていました。私はHttpContext.RewritePathを使用して終了:

​​
+1

これを共有してくれてありがとう。 URLのリライトの解決策を探していて、これはどこでも可能です。私は入力解析ではなく、JSとCSSファイルのバージョン管理に使用しています。 –

+0

興味のある方は 'filename.v1234.js'という形式のファイルを管理するために私は' private readonly Regex regJS = new Regex( "^(。*)([。] v [0-9]私は '' Context.RewritePath(string.Format( "{0} {1}"、matchJS.Groups [1])を実行します。 ] .Value、matchJS.Groups [3] .Value)); ' –

3

あなたは私も、このアプローチを好むあなたの静的を処理するためのTransferRequestHandlerを追加する必要があり、次の答え https://stackoverflow.com/a/21724783/22858

+0

参考までに、これはMVC以外のアプリケーションでも有効です。 – Ian

関連する問題