私のテーマには、ある種のパンくずリストがあります。コントローラは常にカテゴリです。繰り返しになるのを避けるために、次のようなすべてのアクションについて、コントローラーのコンストラクターに設定します。
class MyController:Controller{
public MyController() {
ViewBag.BreadcrumbCategory = "MyCategory";
}
}
レイアウトビューでViewBag.BreadcrumbCategory
にアクセスすると、nullになります。アクションでは、それは機能します:
class MyController:Controller{
public IActionResult DoSomething() {
ViewBag.BreadcrumbCategory = "MyCategory";
}
}
コンストラクターでViewBagプロパティを設定できないのではないかと思いますか?この作業を行うすべてのアクションで関数が呼び出されるのは煩わしく、良い習慣ではありません。 別の質問 では、コンストラクターの使用は受け入れられた答えでしたが、私が言ったように、少なくともASP.NETCoreではこれは機能しません。
GitHubの問題 があり、これは仕様によるものであると述べられています。リンクした答えは、古いレガシーASP.NETスタックであるASP.NETMVC3に関するものです。
ASP.NET Coreはゼロから作成され、さまざまな概念を使用して、移植性(複数のプラットフォーム)と、依存性注入の組み込みサポートなどのパフォーマンスと最新のプラクティスの両方を考慮して設計されています。
最後の1つでは、コンストラクターでViewBag
を設定できません。これは、渡す必要がないことに気付いたかもしれないので、Constructor
基本クラスの特定のプロパティをプロパティインジェクションを介して注入する必要があるためです。派生コントローラーのこれらの依存関係。
つまり、Controller
のコンストラクターが呼び出されたときに、HttpContext
、ControllerContext
などのプロパティは設定されません。それらは設定されるだけですafterコンストラクターが呼び出され、このオブジェクトへの有効なインスタンス/参照があります。
また、GitHubの問題で指摘されているように、これは仕様によるものであるため、修正されません。
ご覧のとおり、 ここ 、ViewBagはViewData
に依存しており、コントローラーの初期化後にViewData
が設定されます。 ViewBag.Something = "something"
を呼び出すと、DynamicViewData
クラスの新しいインスタンスが作成され、コンストラクターが初期化された後にインスタンスに置き換えられます。
@SLaksが指摘しているように、コントローラーごとに構成するアクションフィルターを使用できます。
次の例では、alwaysコントローラーをController
基本クラスから派生させることを前提としています。
public class BreadCrumbAttribute : IActionFilter
{
private readonly string _name;
public BreadCrumbAttribute(string name)
{
_name = name;
}
public void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
var controller = context.Controller as Controller;
if (controller != null)
{
controller.ViewBag.BreadcrumbCategory = _name;
}
}
}
これで、コントローラーをそれで飾ることができるはずです。
[BreadCrumb("MyCategory")]
class MyController:Controller
{
}
私は同じ問題を抱えており、コントローラーのOnActionExecuted
メソッドをオーバーライドして解決します。
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
ViewBag.Module = "Production";
}