私は多くの ASP.Net MVC サイトを構築しました。それぞれのサイトには、MVC のコントローラーとアクションに適したページがいくつかあり、実際には単なるパンフレット ページであるページがいくつかあります - /why、/why/ouradvantage、 /about など - 実際の機能を持たず、ビューだけ、おそらくレイアウトだけのページ、それだけです。
これらのパンフレット スタイルのページでは、View とそれを見つけるための適切な Route のみを使用したいので、/why を /Brochure/Why.cshtml または /Brochure/Why/Index.cshtml に配置し、いずれかの方法で配置できます。ちゃんと拾われます。この一連の URL とページを処理するために (過去に行ったように) ばかげたコントローラーとアクションを作成することは避けたいと思います。
ASP.Net MVC プロジェクトでこれを行うにはどうすればよいですか? これは共通のニーズでなければなりません。
編集:これを詳細な方法で行う方法の例:
標準の MVC ルート ({controller}/{action}/{id}) を使用して、必要な一連の URL とページを取得するために大量の役に立たない Controller をスパムすることができます。パンフレット スタイル (機能なし、ビューのみ) のページを追加するたびに、次のようにコントローラーまたはアクションを追加します。
なぜコントローラ:
public class WhyController : Controller
{
public ViewResult Index()
{
return View();
}
public ViewResult OurAdvantage()
{
return View();
}
}
これにより、View が /why および /why/ouradvantage に配置されます (クリーンな URL)。/about ページが必要な場合は、AboutController という名前のビューを返すだけの別のコントローラーを追加できます。5 つのサブページがある場合、そのコントローラーに 5 つのアクションを追加できます。これらのアクションはすべてビューを返すだけです。
MVC サイトのこれらのパンフレット スタイルのページが 100 ページに達するとしたら、かなりの数の不必要なコントローラーとアクションがすべて実際には何もしていないことになります。あまり乾燥していません。ビューをプロジェクトのフォルダーに配置し、/why や /why/ouradvantage などのクリーンな URL で、そこにあるためだけにアクセスできるようにする方法に興味があります (規約による構成)。
私を近づけるいくつかの方法があります:
大量の .cshtml ページを配置して直接アクセスすることもできますが、URL にファイル拡張子を含める必要があり、View ファイル自体をルートに配置する必要があります。
ASP.Net Areas を使用してこれらの Area を定義することもできますが、すべてのパンフレット スタイルのページは少なくとも 1 つの URL セグメントの深さに配置する必要があり、URL のファイル拡張子に関する上記の問題が依然として残っています。
私が定義できるクレイジーなルートがあります。
これは、これらのパンフレット スタイルのページの数が少ないか多い MVC プロジェクトでよく発生するのではないかと思います。これを行うためのクリーンな方法があるはずです。
EDIT:ルーティングエンジンをスパムするくだらないソリューション。
次のようなルートをマップするクラスを作成します。
public static void MapRoutes(RouteCollection routes, string appRoot, string path)
{
if (!path.Contains("~/"))
throw new NotSupportedException("Pages path must be virtual (use ~/ syntax).");
var physicalPath = appRoot + path.Substring(2).Replace("/", "\\");
var dir = new DirectoryInfo(physicalPath);
var pages = dir.GetFiles("*.cshtml", SearchOption.AllDirectories);
int rootLength = appRoot.Length;
var rootParsed = pages.Select(p => "~/" + p.FullName.Substring(rootLength).Replace("\\", "/"));
int folderPathLength = path.Length + 1;
var mapped = rootParsed.Select(p => new {
Url = p.Substring(folderPathLength, p.Length - 7 - folderPathLength),
File = p
});
var routedPages = mapped.Select(m => routes.MapRoute(
name: m.Url,
url: "{*url}",
defaults: new { path = m.File, Controller = "Brochure", Action = "Catchall" },
constraints: new { url = m.Url }
)).ToArray();
}
次のように RouteConfig でこれを呼び出すことができます。
BrochureRoute.MapRoutes(routes, Server.MapPath("~/"), "~/Brochure");
これにより、これらすべてのページが BrochureController にマップされます。これも必要になります。
public class BrochureController : Controller
{
public ViewResult Catchall(string path)
{
return View(path);
}
}
2 つの問題:
- 前述のように、ルーティング エンジンにスパムを送信します。100 ページある場合は、100 のルートがあります。
- 上記のようにパスを渡すと、通常の Razor パイプラインが混乱するようです。この方法でページにアクセスすると、次のようなエラーが発生します。
'~/Brochure/About.cshtml' のビューは WebViewPage から派生する必要があります