ASP.Net MVC キャッシュを備えたデータベース駆動型メニュー
-
21-09-2019 - |
質問
自分のウェブサイト用のメニューを作成しようとしています。以下の要件を満たす必要があります
- データベース駆動型である必要があり、DB からデータを取得してメニュー構造を構築する必要があります。
- DB から取得されるデータはキャッシュする必要があります。ページリクエストごとに DB にアクセスしたくないです。
現時点では、単純なサンプルを実行していますが、キャッシュを統合する方法がわかりません。おそらくやり方を全部やり直す必要があると思います。ここにあります:
私は持っています 製品メニュー属性, 、DB からデータを取得し、ViewData に保存します。
public class ProductMenuAttribute: FilterAttribute, IActionFilter
{
#region IActionFilter Members
public void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext != null)
{
var context = filterContext.Result as ViewResult;
if (context != null)
{
ProductsRepository repository = new ProductsRepository(Properties.Settings.Default.SqlConnectionString);
context.ViewData.Add("ProductsList", repository.GetAllProductRanges());
}
}
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
#endregion
}
私の中で サイトマスター からデータを引き出します データの表示 それを使ってメニューをレンダリングします。これは、CSS を使用してスタイル設定された、順序付けされていないメニュー リストの小さなスニペットです。コードは次のとおりです。
<li>
<%= Html.ActionLink("Products", "Index", "Products")%>
<% IQueryable<ProductRange> productRanges = ViewData["ProductsList"] as IQueryable<ProductRange>; %>
<% if (productRanges != null)
{ %>
<ul>
<% foreach (ProductRange range in productRanges)
{ %>
<li><%= Html.ActionLink(range.Name, "RangeDetails", "Products", new { id = range.ID }, null)%></li>
<% } %>
</ul>
<% } %>
</li>
次に、各コントローラーを 【商品メニュー】 次のように属性を付けます。
[ProductMenu]
public class HomeController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
これで、コントローラー上のいずれかのアクションがヒットするたびに、 アクションの実行時 のメソッド 製品メニュー属性 クラスが呼び出され、ViewData が設定され、最終的には私の環境で使用されます。 サイトマスター DB からメニューを構築し、その際にアクションのいずれかを呼び出します。
ここでの問題は、このシナリオにキャッシュを追加するにはどうすればよいでしょうか??どこから始めればよいのか見当もつきませんし、私が持っているソリューションはキャッシュ可能ではないような気がします。
解決
私が本当に探しているのは、 Html.RenderAction() MVC Futures プロジェクトのヘルパー拡張機能。
このアイデアは、上記のコードを使用してコントローラー上のアクションを呼び出し、DB からデータを取得して HTML メニュー構造を生成するというものです。次に、単純な出力キャッシュを使用して、データを数分間キャッシュします。
これは、私が望むことを達成するためにこれまでに見つけた最も簡単なアプローチです。
編集: Phil Haack が最近これについてブログに書きました - Html.RenderAction と Html.Action. 。私の正確なニーズをすべてカバーし、すべての問題の説明を含む素晴らしいブログ投稿です。
キャッシュを正しく機能させるには、次のようにする必要があります。 Html.RenderAction()
内部で呼び出します ビューユーザーコントロール OutputCaching ディレクティブを次のように設定します。
<@ OutputCache Duration="100" VaryByParam="None" %>
次に、上記を呼び出します Html.RenderPartial()
, さあ、すべてうまくいきました。
他のヒント
キャッシュを認識するようにリポジトリを変更できます。この 2 つの質問を参照してください。キャッシュされたリポジトリ そして httpキャッシュ.
私は、エンタープライズライブラリキャッシュブロックを使用してこれを行っています。キャッシュされたデータが存在しない場合は、データベース内のデータからHTML文字列を作成し、キャッシュされたデータを検索するとき、あなただけの出力プレーンな文字列をすることができますので、後でキャッシュに入れて、キャッシュされたデータをチェック:D
だけがそれを行うためにそのコードを言及するためには、静的クラスにいました。病気ポスト例が、私は手でコードを持っていけないので、私は最初からMVC2でそのアプリを書き換えています。