2013-10-04 50 views
2

在我的ASP.NET MVC4中,我允許控制器通過設置ViewBag.PageTitle來設置當前頁面標題。 但在ASP.NET MVC中通過子動作設置頁面標題

第1部分。當ViewBag.PageTitle在ChildAction中設置時(_Layout.cshtml沒有看到它),它不工作。我如何從ChildAction中設置頁面標題?

第2部分。如何在緩存的ChildAction中設置頁面標題,因爲該操作在緩存時不再被調用?

謝謝!

public ActionResult Product(long productId) 
{ 
    ViewBag.PageTitle="test"; //Works 
    return View(productId); 
} 

[OutputCache(Duration=300)] 
[ChildActionOnly] 
public ActionResult ProductPartial(long productId) 
{ 
    Product product=AProductProvider.Instance.GetProduct(productId); 
    ViewBag.PageTitle=product.Name; //Doesn't work 

    return View(product); 
} 

回答

5

您可以使用ControllerContext.ParentActionViewContext檢索有關父視圖的信息:

[OutputCache(Duration = 300)] 
[ChildActionOnly] 
public ActionResult ProductPartial(long productId) 
{ 
    Product product = AProductProvider.Instance.GetProduct(productId); 
    ControllerContext.ParentActionViewContext.ViewBag.PageTitle = product.Name; 

    return View(product); 
} 

UPDATE:對於這項工作,在你的父視圖你要調用的ViewData,如:

@ViewContext.ViewData["PageTitle"] 

原因有點模糊。子動作接收適當的參考父動作的的ViewData(對象的相同的實例),但每視圖(的ViewPage)視圖初始化期間接收的ViewData的拷貝在原始狀態的ViewData具有Sytem.Web.Mvc.Html.TemplateHelpers.TemplateHelper方法。在調用子動作之前,父頁面的ViewData被初始化/複製,所以後面的子動作更新不適用。這是MVC的源代碼,做的是:

// .... 
ViewDataDictionary viewData = new ViewDataDictionary(html.ViewDataContainer.ViewData) 
{ 
    Model = metadata.Model, 
    ModelMetadata = metadata, 
    TemplateInfo = new TemplateInfo 
    { 
     FormattedModelValue = formattedModelValue, 
     HtmlFieldPrefix = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName), 
     VisitedObjects = new HashSet<object>(html.ViewContext.ViewData.TemplateInfo.VisitedObjects), // DDB #224750 
    } 
}; 

然而,ViewContext不斷引用,不是副本控制器上下文數據,因此你可以使用一個。另一方面,如果您使用ViewContext.ViewData,您必須瞭解視圖的執行順序,子動作,部分,佈局...

+0

我希望它能夠工作!不幸的是,ViewBag.PageTitle沒有爲佈局保留空白。它不會以另一種方式工作,當我設置ViewBag.PageTitle =「test」;在行動中,我無法在ChildAction中檢索該值。 – Vincent

+0

我可能有問題,因爲父動作設置的值現在可以正確地用於子節點;然而:在_Layout級別它仍然是空的,並且仍然存在緩存問題:/(我無法緩存整個頁面,因爲我顯示了用戶特定的信息,但是如果它出現在ASP.NET MVC Donut Caching中可以解決我的問題) – Vincent

+0

對於緩存部分,我會嘗試以不同方式撰寫/拆分操作和視圖。即使從兒童視角設置標題也不會讓我覺得對。這看起來像我的頁面的主要部分,特別是如果它確定頁面的標題。 – Nenad