By default the new project template for ASP.NET MVC 3 adds the following to the default layout (masterpage in razor):
@ViewBag.Title
<
I like to create a PageTitle ActionFilter attributes rather than editing individual ViewBags
Usage: keep the view the same
<title>@ViewBag.Title</title>
For controller-wide page title:
[PageTitle("Manage Users")]
public class UsersController : Controller {
//actions here
}
For individual views:
public class UsersController : Controller {
[PageTitle("Edit Users")]
public ActionResult Edit(int id) {
//method here
}
}
Attribute Code:
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;
}
}
}
Easy to manage and works like a charm.
For me personally, I think this case is an acceptable use of ViewBag
. It is limited to a "well-known" property, and it likely won't cause any problems in the future. In the end, it is all about being pragmatic and finding a way to be as quick as possible. Having a base class where you need to set the title would in my opinion be too much code to be worth the type safety.
Good luck!
I would say that as long as it's only the Title you want to set, it's ok to use the ViewBag. Well, maybe not only - at most 2-3 properties.
But if you start to see you're setting more and more (common) properties in every controller action, I would go with a strongly typed "ViewModelBase class". But it's just me.
ViewBag for title is perfectly fine (I'd even say it is the purpose of having ViewBag) - dynamic is not the absolute evil. "Title" is well known, unlikely to change and even predefined in view templates. I personally use following title:
<title>@(ViewBag.Title == null ? string.Empty : ViewBag.Title + " | ")Site Name</title>
If you are worried about mistyping ViewBag.Title
you can make it strong type by creating custom WebViewPage
but you will still have to use ViewBag
or maybe HttpContext.Items
inside that strongly typed property because there are multiple instances of WebViewPage
created during rendering IIRC.
I'd recommend to stick with ViewBag
, creating own WebViewPage
because of this seems like overkill - even creating single property on it if you already have custom WebViewPage
is in my opinion just worthless complication - and that comes from person that is often overengineering things.
I don't think there is any thing bad with default title handling feature that ships with asp.net MVC 3, its okay to do.
I personally do this(below written) to handle title, I am not endorsing the below code or saying that its better than default functionality, its just a preference.
Master
<title>
@RenderSection("Title");
</title>
View
@section Title
{
write title
}
One thing i could suggest to improve default functionality
@{
string pageTitle = @ViewBag.Title ?? "Title Not Set";
}
<title>@pageTitle</title>
So whenever you forget to add it in viewbag, the page will display title= Title Not Set
Creating a base class then making all your controllers inherit from that base-class can also be done. But I think its taking so much of pain for title
.
There is nothing wrong with using ViewBag.Title = "My Title";
All you are doing is use a dynamic property.
The question is really where the information should be "declared".
Ie, where is it most accessible for the purposes at hand.
If it is on a per page basis, then that is the right place.
If, however, the title of the page can be derived from the Model, then you should do that.
In this case, I would probably use a base class for the ViewModel that you use, and create a PageTitle property there that contains the logic to derive the page title from properties in the Model.
So:
<title>Model.PageTitle</title>
In summary, horses for courses and don't be afraid of using dynamic properties... so long as you understand what they are and what they do.