2011-08-08 150 views
24

默認情況下,ASP.NET MVC 3的新項目模板中添加以下爲默認佈局(在剃刀的母版):替代ViewBag.Title在ASP.NET MVC 3

<title>@ViewBag.Title</title> 

視圖必須再包含以下指定頁面的標題,例如:

@{ 
    ViewBag.Title = "Log On"; 
} 

也許這只是我自己的偏好,但我發現使用ViewBag舉行標題有點不對(我想得太多了魔串風味)。所以我的問題是:對於使用ASP.NET MVC 3和剃鬚刀(使用動態屬性包)的用戶,或者您是否選擇更強類型的內容(可能涉及自定義基類?),這是推薦的最佳做法嗎?

+1

對此使用viewbag非常棒,因爲您可以在佈局頁面中聲明變量,然後爲每個從其繼承的視圖指定不同的標題。沒有使用靜態類型的模型,真的沒有其他方法可以做到。 –

回答

25

I不要認爲使用asp.net MVC 3附帶的默認標題處理功能有什麼不好的,它可以做。

我個人這樣做(下面寫)處理標題,我不認可下面的代碼或說它比默認功能更好,它只是一個偏好。

<title> 
    @RenderSection("Title"); 
</title> 

查看

@section Title 
{ 
    write title 
} 

有一件事我可以建議改善默認功能

@{ 
    string pageTitle = @ViewBag.Title ?? "Title Not Set"; 
} 
<title>@pageTitle</title> 

所以每當你忘了添加在viewbag,頁面將顯示標題= Title Not Set

創建一個基類,然後讓所有控制器繼承該基類,也可以完成。但我認爲它爲title帶來了如此多的痛苦。

+0

只是爲了澄清(我沒有想到一個默認的控制器基類,我一直在想,你可以爲視圖創建你自己的派生基類(我認爲剃刀讓你這麼做),並在這個類中展示一個PageTitle屬性,可以分配和佈局可以呈現) –

+0

我喜歡這個'@ViewBag.Title ?? 「默認」方法。它可以移動到_ViewStart.cshtml,您可以在此爲所有共享屬性設置默認值。 – Darmak

+0

@ soren.enemaerke:假設你爲視圖創建了一個基類來處理頁面標題,可能在你的視圖中你會設置標題像這樣@ {this.pageTitle =「New Title」;},同時你可以設置默認的功能標題像@ {ViewBag.Title =「新標題」;}。語法沒有太大區別。使用此代碼獲得的另一個好處是ViewBag.Title =「something」,您可以在視圖或控制器中設置標題,兩者都可以工作。 –

1

對我個人而言,我認爲這種情況是ViewBag的可接受使用。它僅限於一個「知名」的財產,並且它可能不會在未來造成任何問題。最後,這是所有關於務實和尋找儘可能快的方法。有一個基類,你需要設置標題在我看來是太多的代碼值得類型安全。

祝你好運!

1

我會說,只要它只是你想設置的標題,就可以使用ViewBag。那麼,不僅可能 - 最多2-3個屬性。

但是,如果你開始看到你在每一個控制器動作中設置越來越多的(通用)屬性,我會使用強類型的「ViewModelBase類」。但這只是我。

7

ViewBag for title是非常好的(我甚至會說這是ViewBag的目的) - 動態不是絕對的邪惡。 「標題」是衆所周知的,不太可能改變,甚至在視圖模板中預定義。我個人使用以下標題:

<title>@(ViewBag.Title == null ? string.Empty : ViewBag.Title + " | ")Site Name</title> 

如果你擔心打錯ViewBag.Title你可以通過創建自定義WebViewPage使其強大的類型,但你仍然必須使用ViewBag也許HttpContext.Items是強類型屬性裏面,因爲有多個渲染IIRC期間創建的實例WebViewPage

我建議你堅持使用ViewBag,創建自己的WebViewPage,因爲這似乎有點小題大做 - 甚至創造它單一的財產,如果你已經有自定義WebViewPage在我看來只是毫無價值的併發症 - 以及來自人是往往過度工程的東西。

+0

或只是' @(ViewBag.Title ?? ViewBag.Title +「|」)網站名稱'儘量縮短。 – schaermu

+0

@schaermu你的建議不起作用,它會導致'|如果尚未設置Title屬性,則爲「站點名稱」。 –

1

我們更喜歡強大的標題設置..我們的BaseController類中的幾個示例。 (頁面定義了封裝視圖模式)

protected override ViewResult View(string viewName, string masterName, object model) 
{ 
    if (model is Page) 
    { 
     ViewBag.Title = ((Page)model).Title; 
     //HACK: SEO 
     //TODO: SEO 
    } 
    return base.View(viewName, masterName, model); 
} 
1

使用ViewBag.Title =「My Title」;

您所做的只是使用動態屬性。

這個問題真的在哪裏應該是「聲明」的信息。

也就是說,哪裏最容易達到目的。

如果它是在每個頁面的基礎上,那麼這是正確的地方。

但是,如果該頁面的標題可源自模型,那麼你應該這樣做。

在這種情況下,我可能會使用一個基類爲您所使用的視圖模型,並創建的PageTitle性質有一個包含從示範性導出頁面標題的邏輯。

所以:

<title>Model.PageTitle</title> 

綜上所述,馬場,當你明白他們做他們是什麼,什麼不要害怕使用動態特性......這麼長時間的。

2

我喜歡創造的PageTitle ActionFilter屬性,而不是編輯個人ViewBags

用法:保持視圖同

<title>@ViewBag.Title</title> 

對於控制器級頁面標題:

[PageTitle("Manage Users")] 
public class UsersController : Controller { 
    //actions here 
} 

對於個人觀點:

public class UsersController : Controller { 
    [PageTitle("Edit Users")] 
    public ActionResult Edit(int id) { 
      //method here 
    } 
} 

屬性代碼:

public class PageTitleAttribute : ActionFilterAttribute 
{ 
    private readonly string _pageTitle; 
    public PageTitleAttribute(string pageTitle) 
    { 
     _pageTitle = pageTitle; 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     base.OnActionExecuted(filterContext); 
     var result = filterContext.Result as ViewResult; 
     if (result != null) 
     { 
      result.ViewBag.Title = _pageTitle; 
     } 
    } 
} 

易於管理和工程就像一個魅力。

+0

頁面標題應設置在視圖中而不是控制器。 –

+0

應該嗎?假設您重複使用視圖來上傳不同類型的文件?例如。 MyFiles/UploadExcel,MyFiles/UploadCsv ... – nh43de

3

我也根本不使用ViewBag。

在_Layout.shtml的頂部...

@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel 

在_Layout.shtml ...

<title>@Model.Title</title> 

在你的模型...

/// <summary> 
/// Index View Model 
/// </summary> 
public class IndexViewViewModel : EveryPageViewModel { 

} 

在EveryPageViewModel

/// <summary> 
/// Every Page View Model 
/// </summary> 
public abstract class EveryPageViewModel { 
    /// <summary> 
    /// Title 
    /// </summary> 
    public string Title { get; set; } 
    /// <summary> 
    /// Sub Title 
    /// </summary> 
    public string SubTitle { get; set; } 
} 

在你的控制器動作

/// <summary> 
    /// Index 
    /// </summary> 
    /// <returns></returns> 
    public ActionResult Index() { 
     var model = new IndexViewViewModel(); 
     model.Title = "Home"; 
     return View(model); 
    }