3

アプリケーションでメニュー項目を表すために使用される ListItem クラスがあります。

 public class ListItem : Entity
{
    public virtual List List { get; set; }
    public virtual ListItem ParentItem { get; set; }
    public virtual ICollection<ListItem> ChildItems { get; set; }

    public int SortOrder { get; set; }
    public string Text { get; set; }
    public string Controller { get; set; }
    public string Action { get; set; }
    public string Area { get; set; }
    public string Url { get; set; }
}

このデータを使用してアプリケーションのルートを構築していますが、静的コンテンツのコントローラー/ビューを処理するクリーンな方法があるかどうか疑問に思っていましたか? 基本的に、データを使用せず、ビューのみを使用するページ。現在、StaticContentController と呼ばれるコントローラーが 1 つあります。これには、静的ページごとに次のような適切なビューを返す固有のアクションが含まれています。

public class StaticContentController : Controller
{

    public ActionResult Books()
    {
        return View("~/Views/Books/Index.cshtml");
    }

    public ActionResult BookCategories()
    {
        return View("~/Views/Books/Categories.cshtml");
    }

    public ActionResult BookCategoriesSearch()
    {
        return View("~/Views/Books/Categories/Search.cshtml");
    }
}

これを最小限に抑えて、静的コンテンツ用のコントローラー/アクションをそれほど多くする必要がないようにする方法はありますか? ListItem データを作成するときに、コントローラーを静的コンテンツを処理する特定のコントローラーに設定できるようですが、とにかく 1 つの関数を使用して、返すビューを計算することはできますか? まだ別のアクションが必要なようです。そうしないと、ユーザーがどのページにアクセスしようとしていたのかわかりません。

ListItem.Url には、ルートの作成に使用されるアプリケーション ルートからの完全な URL パスが含まれています。プロジェクト内のビューの場所は、組織構造を平行に保つために URL の場所に対応します。

助言がありますか?ありがとう。

編集:私のルート登録は次のようになります:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("Shared/{*pathInfo}");
        routes.MapRoute("Access Denied", "AccessDenied", new { controller = "Shared", action = "AccessDenied", area = "" });
        List<ListItem> listItems = EntityServiceFactory.GetService<ListItemService>().GetAllListItmes();
        foreach (ListItem item in listItems.Where(item => item.Text != null && item.Url != null && item.Controller != null).OrderBy(x => x.Url))
        {
            RouteTable.Routes.MapRoute(item.Text + listItems.FindIndex(x => x == item), item.Url.StartsWith("/") ? item.Url.Remove(0, 1) : item.Url, new { controller = item.Controller, action = item.Action ?? "index" });
        }

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );


    }
4

1 に答える 1

11

すべての静的ページを返す 1 つのパラメーター (ビュー名) を持つ単一のアクションを使用できます。

public class StaticContentController : Controller
{
    public ActionResult Page(string viewName)
    {
        return View(viewName);
    }
}

これらのビューを提供するためのカスタム ルートも作成する必要があります。次に例を示します。

routes.MapRoute(
    "StaticContent",                                      // Route name
    "page/{viewName}",                                    // URL with parameters
    new { controller = "StaticContent", action = "Page" } // Parameter defaults
);

あなたの例では、ビューに異なるフォルダーを指定していることがわかります。このソリューションでは、すべての静的ビューを StaticContentController の Views フォルダーに配置する必要があります。

カスタムのフォルダー構造が必要な場合は、このよう/に追加*することで受け入れるルートを変更できます。これで、次のルートを使用できます: . 入力パラメータで受け取り、好きなように返すことができます:{viewName}{*viewname}/page/Books/CategoriesviewName"Books/Categories"return View(string.Format("~/Views/{0}.cshtml", viewName));

UPDATE (page/接頭辞を避ける)

アイデアは、ファイルが存在するかどうかを確認するためのカスタム制約を持つことです。特定の URL に存在するすべてのファイルは、静的ページとして扱われます。

public class StaticPageConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        string viewPath = httpContext.Server.MapPath(string.Format("~/Views/{0}.cshtml", values[parameterName]));

        return File.Exists(viewPath);
    }
}

ルートを更新します。

routes.MapRoute(
    "StaticContent",                                       // Route name
    "{*viewName}",                                         // URL with parameters
    new { controller = "StaticContent", action = "Page" }, // Parameter defaults
    new { viewName = new StaticPageConstraint() }          // Custom route constraint
);

アクションを更新します。

public ActionResult Page(string viewName)
{
    return View(string.Format("~/Views/{0}.cshtml", viewName));
}
于 2012-06-21T14:41:00.090 に答える