ルーティング オプションを実行するには、URL が実際の画像にどのようにマップされるかについて、何らかの仕様を考え出す必要があります。私たちは何枚の画像について話しているのですか?1000? 10,000? 100万?100,000 未満の場合は、おそらく先に進んで、既に作成した仕様を使用して、すべてのファイルの名前を変更し、その仕様を使用して、ファイル システムに入る途中でファイルに名前を付けます。
このシステムの利点は、データへの変更の範囲を制限し、システムの 1 つのポイント (ファイルが途中である場合) にのみ影響を与える必要があることです。パフォーマンスに関して言えば、文字列を別の文字列にマッピングするオーバーヘッドは、多数のリクエストの場合でもおそらく無視できます。短い文字列の文字列操作は非常に高速ですが、リクエストに時間がかかりすぎた場合はリクエスト全体をプロファイリングし、主要な問題点に集中する必要があります。もちろん、ファイルの名前を変更するだけであれば、このプロファイリングについて心配する必要はありません。
URL のマッピングを行うためのルートの作成に関しては、最初に ASP.NET にリクエストをコードに渡させる必要があります。デフォルトでは、ASP.NET は最初に URL で指定された場所にファイルが存在するかどうかを確認し、存在する場合は、IIS に登録されたハンドラーに基づいてファイルを処理します。これらの設定を変更すると、システムに非常に大きな変更が加えられるため、これらの設定をそのままにしておくことをお勧めします。画像の場合、ハンドラーはファイルをクライアントに送信しようとします。
ファイルがディスク上に存在しない場合は、ルート コレクションを繰り返し処理することにより、リクエストのハンドラを探します。ルート コレクションは、通常は でルートを登録するものですGlobal.asax
。何を試したかを教えてくれなかったので、ルートがどのように機能するかを知っていると仮定します。ルートを巧妙に使うこともできますが、ここでは単純なものに固執します。
routes.MapRoute(
name: "images",
url: "{folder}/images/productimage/{unmappedFileName}",
defaults: new { controller = "Home", action = "Images" }
);
このルートは、指定した URL の例と一致します。ただし、実際のファイル名を使用する場合、上記で説明したように、このルートはヒットしません。ただし、SEO されたファイル名が存在しないため、このルートがヒットし、Home コントローラーで Images アクションを実行しようとします (これらのパーツがどこに行くかについての混乱を避けるために、ここに Home コントローラー全体をリストします)。
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Images(string unmappedFileName)
{
if (String.IsNullOrWhiteSpace(unmappedFileName))
{
return HttpNotFound();
}
var fileName = MapFileName(unmappedFileName);
var diskLocation = GetDiskLocation(fileName);
return File(diskLocation, "image/png");
}
private string MapFileName(string unmappedFileName)
{
return unmappedFileName + ".png";
}
private string GetDiskLocation(string fileName)
{
var fullPath = String.Format("~/Content/themes/base/images/{0}", fileName);
var diskLocation = Server.MapPath(fullPath);
return diskLocation;
}
}
明らかに、ファイル名のマッピングを、決定した仕様に更新する必要があります。新しい MVC4 プロジェクトを作成すると、そのフォルダーにサンプル ファイルがたくさんあるので、ここにあるものを使用しています。
それが機能することを示す簡単な方法は、次のように Home フォルダーに Index ビューを実装することです。
{
ViewBag.Title = "Index";
var imagesDirectory = Server.MapPath("~/Content/themes/base/images/");
var imageFileNames = Directory.GetFiles(imagesDirectory).Select(m => m.Replace(imagesDirectory, "").Replace(".png", ""));
}
<h2>Index</h2>
@foreach (var imageFileName in imageFileNames)
{
<div>@Html.ActionLink(imageFileName, "Images", new { unmappedFileName = imageFileName })</div>
}
将来、このような問題に遭遇した場合は、まずそれを理解しようとする必要があります. 質問をするときは、問題を解決するためのコードを私たちに尋ねるだけでなく、次の困難を乗り越えて正しい方向に導くことができるように、あなたが試したことを必ず教えてください. どこから始めればよいかわからない場合は、検索するか、より抽象的な質問をしてみてください。他の質問にも同時に答えてくれるかもしれません。:)
最後に、このソリューションは非常に複雑です。マッピング関数がどのように機能するかさえわかりませんが、これが複雑であることはわかっています。また、デバッグ時に複雑なレイヤーが追加されます。これは、所有している URL がディスク上のファイル名に直接関連していないためです。その時間は後で加算されます。もちろん、私がこのマッピングを好む理由はいくつかあります。最も顕著なのは、将来SEOのさらなる変更のために URL 構造を変更するつもりである場合です。本当に、可能であれば、すべてのファイル名を変更することをお勧めします。