25

默认情况下,ASP.NET MVC 3 的新项目模板将以下内容添加到默认布局(剃刀中的母版页):

<title>@ViewBag.Title</title>

视图必须包含以下内容来分配页面的标题,例如:

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

也许这只是我自己的偏好,但我发现使用 ViewBag 来保存标题有点错误(我在想太多的魔法字符串味道)。所以我的问题是:对于使用 ASP.NET MVC 3 和 razor(使用动态属性包)的人来说,这是推荐的最佳实践,还是您选择更强类型的东西(可能涉及自定义基类?)

4

8 回答 8

28

我认为 asp.net MVC 3 附带的默认标题处理功能没有什么不好的,可以这样做。

我个人这样做(下面写)来处理标题,我不认可下面的代码或说它比默认功能更好,它只是一个偏好。

掌握

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

看法

@section Title
{
    write title
}

我可以建议改进默认功能的一件事

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

所以每当你忘记在viewbag中添加它时,页面会显示title=Title Not Set

也可以创建一个基类,然后让所有控制器都从该基类继承。但我认为它为此付出了很多痛苦title

于 2011-08-08T09:05:01.757 回答
7

标题的 ViewBag 非常好(我什至会说这是拥有 ViewBag 的目的) - 动态并不是绝对的邪恶。“标题”是众所周知的,不太可能更改,甚至在视图模板中预定义。我个人使用以下标题:

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

如果您担心ViewBag.Title输入错误,您可以通过创建自定义使其成为强类型,WebViewPage但您仍然必须使用ViewBag或者可能HttpContext.Items在该强类型属性中,因为WebViewPage在呈现 IIRC 期间创建了多个实例。

我建议坚持ViewBag,创建自己的,WebViewPage因为这似乎有点矫枉过正——如果你已经有自定义,即使在其上创建单个属性WebViewPage在我看来只是毫无价值的复杂化——这来自经常过度设计事物的人。

于 2011-08-08T09:34:25.897 回答
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);
    }
于 2016-12-22T17:00:40.603 回答
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;
        }
    }
}

易于管理,工作起来就像一个魅力。

于 2015-03-20T14:13:30.053 回答
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);
}
于 2011-08-08T09:36:59.187 回答
1

就我个人而言,我认为这种情况是可以接受的ViewBag。它仅限于“知名”属性,并且将来可能不会引起任何问题。最后,这一切都是为了务实并找到一种尽可能快的方法。在我看来,拥有一个需要设置标题的基类将是太多代码,不值得类型安全。

祝你好运!

于 2011-08-08T09:07:04.460 回答
1

使用 ViewBag.Title = "My Title"; 没有任何问题。

您所做的就是使用动态属性。

问题实际上是应该在哪里“声明”信息。

即,对于手头的目的,它在哪里最容易访问。

如果它是基于每页的,那么这是正确的地方。

但是,如果页面的标题可以来自模型,那么您应该这样做。

在这种情况下,我可能会为您使用的 ViewModel 使用一个基类,并在那里创建一个 PageTitle 属性,其中包含从模型中的属性派生页面标题的逻辑。

所以:

<title>Model.PageTitle</title>

总而言之,马为课程而不必害怕使用动态属性...只要您了解它们是什么以及它们做什么。

于 2011-08-08T12:36:24.983 回答
1

我想说,只要是你要设置的Title,用ViewBag就可以了。好吧,也许不仅 - 最多 2-3 个属性。

但是,如果您开始看到您在每个控制器操作中设置了越来越多的(通用)属性,我会使用强类型的“ViewModelBase 类”。但这只是我。

于 2011-08-08T09:12:45.510 回答