Asp.net mvc 3 ASP.NET MVC 3中ViewBag.Title的替代方案

Asp.net mvc 3 ASP.NET MVC 3中ViewBag.Title的替代方案,asp.net-mvc-3,razor,viewbag,Asp.net Mvc 3,Razor,Viewbag,默认情况下,ASP.NET MVC 3的新项目模板将以下内容添加到默认布局(razor中的母版页): 也许这只是我自己的喜好,但我发现使用ViewBag来保存标题有点错误(我想太多魔幻字符串的味道了)。所以我的问题是:对于使用ASP.NET MVC 3和razor(使用动态属性包)的人来说,这是推荐的最佳实践吗?还是您选择的是更强类型的(可能涉及自定义基类?)我认为ASP.NET MVC 3附带的默认标题处理功能没有什么不好的地方,没关系 我个人这样做(写在下面)是为了处理标题,我并不赞同下面的

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


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

我认为ASP.NET MVC 3附带的默认标题处理功能没有什么不好的地方,没关系

我个人这样做(写在下面)是为了处理标题,我并不赞同下面的代码,也不是说它比默认功能更好,只是一种偏好

主人

<title>
    @RenderSection("Title");
</title>
我可以建议改进默认功能的一件事

@{
    string pageTitle = @ViewBag.Title ?? "Title Not Set";
}
<title>@pageTitle</title>
@{
字符串pageTitle=@ViewBag.Title??“未设置标题”;
}
@页面标题
因此,每当您忘记将其添加到viewbag中时,页面将显示title=
title Not Set


还可以创建基类,然后使所有控制器从该基类继承。但是我认为它为
标题
付出了太多的痛苦

就我个人而言,我认为这个案例可以接受使用
ViewBag
。它仅限于一处“知名”的房产,将来可能不会造成任何问题。归根结底,这一切都是关于务实和找到一种尽可能快的方式。在我看来,拥有一个需要设置标题的基类将是太多的代码,不值得使用类型安全性


祝你好运

我想说,只要您只想设置标题,就可以使用ViewBag。嗯,也许不仅仅是-最多2-3个属性


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

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

<title>@(ViewBag.Title == null ? string.Empty : ViewBag.Title + " | ")Site Name</title>
@(ViewBag.Title==null?string.Empty:ViewBag.Title+“|”)站点名称
如果您担心键入错误
ViewBag.Title
可以通过创建自定义
WebViewPage
使其成为强类型,但是您仍然必须使用
ViewBag
或者可能在强类型属性中使用
HttpContext.Items
,因为在该属性中创建了多个
WebViewPage
实例渲染IIRC


我建议坚持使用
ViewBag
,因此,创建自己的
WebViewPage
似乎有点过头了——即使在它上面创建一个属性,如果你已经有了自定义的
WebViewPage
,在我看来,这也是毫无价值的复杂问题——而这来自于经常过度工程的人。

我们更喜欢强的标题设置。。我们的BaseController类中很少有示例。(页面定义封装视图模式)


使用ViewBag没有任何问题。Title=“我的标题”

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

问题实际上是信息应该“申报”到哪里

也就是说,对于手头的目的来说,最容易到达的地方是哪里

如果是以每页为基础,那么这就是正确的位置

但是,如果页面的标题可以从模型派生,那么您应该这样做

在本例中,我可能会为您使用的ViewModel使用一个基类,并在其中创建一个PageTitle属性,该属性包含从模型中的属性派生页面标题的逻辑

因此:

Model.PageTitle

总的来说,马适合于球场,不要害怕使用动态属性。。。只要您了解它们是什么以及它们是做什么的。

我喜欢创建页面标题ActionFilter属性,而不是编辑单个ViewBags

用法:保持视图不变

<title>@ViewBag.Title</title>
个人意见:

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;
        }
    }
}

易于管理,工作起来很有魅力。

我也根本不使用ViewBag

在_Layout.shtml的顶部

@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel
<title>@Model.Title</title>
@model.Models.Base.EveryPageViewModel
在_Layout.shtml中

@model <YourWebAppNameSpace>.Models.Base.EveryPageViewModel
<title>@Model.Title</title>
@Model.Title
在你的模型中

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

}
//
///索引视图模型
/// 
公共类IndexViewModel: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; }
}
//
///每个页面视图模型
/// 
公共抽象类EveryPageViewModel{
/// 
///头衔
/// 
公共字符串标题{get;set;}
/// 
///副标题
/// 
公共字符串字幕{get;set;}
}
在控制器操作中

    /// <summary>
    /// Index
    /// </summary>
    /// <returns></returns>
    public ActionResult Index() {
        var model = new IndexViewViewModel();
        model.Title = "Home";
        return View(model);
    }
//
///索引
/// 
/// 
公共行动结果索引(){
var模型=新的IndexViewModel();
model.Title=“主页”;
返回视图(模型);
}

只是为了澄清(我没有想到默认的控制器基类,我想您可以为视图创建自己的派生基类(我想razor让我们来做),并在该类上公开一个PageTitle属性,视图可以分配该属性,布局可以呈现),我喜欢这样
@ViewBag.Title??“默认”
方法。它可以移动到_ViewStart.cshtml,您可以在此处为所有共享属性设置默认值。@soren.enemaerke:假设您为视图创建了一个基类来处理页面标题,可能在视图中您会这样设置标题@{this.pageTitle=“New title”;},而使用默认功能,您可以设置标题,如@{ViewBag.title=“New Title”;}。语法上没有太大区别。使用此代码ViewBag还有一个好处。Title=“something”,您可以在视图内或控制器中设置标题,两者都可以。接受此作为答案
<title>@Model.Title</title>
/// <summary>
/// Index View Model
/// </summary>
public class IndexViewViewModel : 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);
    }