43

Razor ビュー エンジンで MVC 3 を使用しています。部分ビュー内の ViewBag にいくつかの値を設定し、それらの値を _Layout.cshtml で取得したいと考えています。たとえば、既定の ASP.NET MVC 3 プロジェクトをセットアップすると、"/Views/Shared" フォルダーに _Layout.cshtml ファイルが作成されます。その _Layout.cshtml では、ページ タイトルは次のように設定されます。

<title>@ViewBag.PageTitle</title>

次に、"/Views/Home/About.cshtml" ビューで、ViewBag の内容が変更されます。

@{
    ViewBag.Title = "About Us";
}

これはうまくいきます。Aboutビューがレンダリングされると、ページのタイトルは「About Us」になります。そこで、About ビュー内で Partial ビューをレンダリングし、Partial ビュー内で ViewBag.Title を変更したいと考えています。("/Views/Shared/SomePartial.cshtml")

@Html.Partial("SomePartial")

この部分ビューには、次のコードがあります。

@{
    ViewBag.Title = "About Us From The Partial View";
}

このコードをデバッグすると、ViewBag.Title が「About Us」に設定され、部分ビューでは「About Us From The Partial View」にリセットされますが、コードが _Layout.cshtml にヒットすると、 「私たちについて」に戻ります。

これは、ViewBag のコンテンツが部分ビューで変更された場合、それらの変更はメイン ビュー (About.cshtml) または _Layout.cshtml に表示されない (アクセスできない) ということですか?

前もって感謝します!

4

10 に答える 10

33

ViewBag をパーシャルの viewdatadictionary に渡し、それを引き出す (そしてキャストする) と、好きなことを行うことができ、参照は保持されます。すばらしい点は、動的であるため、プロパティを追加することもでき、親ページの Viewbag に表示されることです。

ページ:

//set the viewbag into the partial's view data
@{Html.RenderPartial("Elaborate", Model, new ViewDataDictionary { {"vb", ViewBag}});}

部分的:

@{
   var vb = ((dynamic)ViewData["vb"]);
   vb.TheTitle = "New values";
 }

ページ

@ViewBag.TheTitle = "New value"
于 2011-03-02T15:55:55.987 に答える
13

私もこの問題を抱えていましたが、きちんとした明白な解決策を見つけることができませんでした。

私が思いついた解決策は、必要なデータを含む、定義した「PageData」クラスを返す Html 拡張メソッドを実装することでした。

    [ThreadStatic]
    private static ControllerBase pageDataController;
    [ThreadStatic]
    private static PageData pageData;

    public static PageData GetPageData(this HtmlHelper html) {
        ControllerBase controller = html.ViewContext.Controller;
        while (controller.ControllerContext.IsChildAction) {
            controller = controller.ControllerContext.ParentActionViewContext.Controller;
        }
        if (pageDataController == controller) {
            return pageData;
        } else {
            pageDataController = controller;
            pageData = new PageData();
            return pageData;
        }
    }

現在のリクエストの最上位コントローラを見つけ、同じ HTTP リクエスト内でメソッドが呼び出されるたびに同じ PageData オブジェクトを返します。新しい HTTP リクエストで初めて呼び出されたときに、新しい PageData オブジェクトを作成します。

于 2011-02-12T21:46:30.197 に答える
8

部分ビューは独自の を取得しViewBagます。

ページの ViewBag は次から取得できます。((WebViewPage) WebPageContext.Current.Page).ViewBag

于 2011-02-11T21:17:13.520 に答える
7

部分ビューでこのトリックを実行して、_Layout.cshtml のタイトルをオーバーライドできます。

@{
    ViewBag.Title = "About Us From The Partial View";
}

......

<script type="text/javascript">
    document.title = "@ViewBag.Title";
</script>
于 2012-11-14T19:40:32.273 に答える
4

他の人がLayoutを指摘しているように、ViewsPartialsは独自のViewBagを取得します。ただし、次のように動作させることができました:ビューまたは部分。

@{ Html.ViewContext.ViewBag.Title = "Reusable Global Variable"; }

次に_Layoutで

@Html.ViewContext.ViewBag.タイトル

ViewContextを明示的に使用することで、ビューは同じ ViewBag を「再利用」します。

于 2012-06-12T00:30:29.033 に答える
3

誰かがまだこれに対する解決策を探している場合は、TempData で解決できるようです。

TempData["x"] = x;

TempData は読み取られるまで保持されるため、_Layout で読み取ることができます。次のリクエストのためにクリアされるように、すべてを読むように注意する必要があります。

于 2017-05-09T11:51:03.010 に答える
1

@SLaks コードを試してみてください

(((WebViewPage) WebPageContext.Current.Page).ViewBag).PropertyName
于 2011-06-07T03:13:11.487 に答える
1

私は次のことを試しましたが、うまくいきます:

(親)ビューで...

@Html.Partial("SomePartial", ViewData, null)

注: ViewDataは引数として渡されmodelますnullが、viewData引数が正しいオーバーロードを使用するように指定する必要があります。ダイナミクスが苦手なViewBagので使えません。Html.Partial

次に、部分ビューで...

@model ViewDataDictionary
@{
    Model["Title"] = "About us from the partial view";
}

もちろん、model実際のモデルに引数を使用する必要がある場合は、より創造的になる必要があります。

于 2013-01-14T14:56:57.867 に答える
-1

mvc3 を使用しているときに同じ問題が発生しました。

this.ViewBag.ViewBag.PropertyName 

カスタム コントロールで動作します。

于 2011-10-27T01:00:52.670 に答える