2011-08-08 148 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); 
    }