1

私は多くの 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 つの問題:

  1. 前述のように、ルーティング エンジンにスパムを送信します。100 ページある場合は、100 のルートがあります。
  2. 上記のようにパスを渡すと、通常の Razor パイプラインが混乱するようです。この方法でページにアクセスすると、次のようなエラーが発生します。

'~/Brochure/About.cshtml' のビューは WebViewPage から派生する必要があります

4

2 に答える 2

1

個々のページをマッピングするRouteCollection.MapPageRouteには、メソッドを使用できます。

routes.MapPageRoute("", "why", "~/Brochure/Why.aspx");

もちろん、Web フォームの代わりに Razor ビュー エンジン (.cshtml) を使用することもできます。

詳細については、MSDN のドキュメントを確認してください。


更新 2

これを .cshtml ページに使用することはできません。ただし、ルーティングを使用して Web ページ (.cshtml ファイル) にアクセスする必要はありません。ファイルを作成し、URL の拡張子を省略するだけで十分です。目的の構造を実現するには、次のようにします。

  • Web プロジェクトでは、Web ページのレンダリングが許可されている必要があります。これを有効にするには、 に移動してweb.configに設定webpages.Enabledtrueます。( <add key="webpages:Enabled" value="true" />)
  • whyWeb アプリケーションのルートにフォルダーを作成する
  • という名前の MVC ViewPage を追加しIndex.cshtmlます。これはhttp://yoursite.com/whyからアクセスできます
  • という名前の MVC ViewPage を追加しouradvantages.cshtmlます。これはhttp://yoursite.com/why/ouradvantagesからアクセスできます。
  • @UrlDataコレクションを使用して URL データにアクセスすることもできます

詳細については、こちらをご覧ください。一般的な Web ページの詳細については、asp.net Web サイトでも入手できます

何らかの理由で本当にルーティングを使用する必要がある場合は、カスタム RouteHandler が必要になります。Nuget に実装されているものを見つけることができます。このパッケージの使用例はこちらです。


アップデート

各ルートを手動で追加することを避けたい場合、選択肢はほとんどありません。

1) パンフレットのページを識別する規則を作成する

これは、デフォルトで URL がパンフレット ページであると想定し、「パンフレットではない」ページを特定のセクションに分離することで実現できます。

routes.MapPageRoute("Default", "{brochurepage}", "~/Brochure/{brochurepage}.aspx");
// isolate non-brochure pages to "site" section
routes.MapRoute(
    "",
    "site/{controller}/{action}/{id}",                      // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

2) コレクションにパンフレットのページ名を保持する

List<string> brochurePages = new List<string>()
{ "about", "why", "contact" }; // add more pages here
....
foreach (var brochurePage in brochurePages)
    routes.MapPageRoute("", brochurePage, "~/Brochure/" + brochurePage + ".aspx");

質問で言及した 2 つの URL について、具体的に説明する必要があります。「/why」と「/why/ouradvantage」のルーティングを実装するには、洗練されたコードを書くことができません。これには特別な処理が必要です。

于 2013-02-18T21:40:39.580 に答える