Reputation: 2945
We have converted our app to be ASP.NET Core but I am having a problem with the ViewBag populating correctly. We have the following base controller
public abstract class ControllerBase : Controller
{
public ControllerBase()
{
ViewBag.Title = "MySite";
}
...// lots of other stuff here also
}
All of our other controllers inherit from ControllerBase
but by the time we get to the view and use the following
@{
ViewBag.Title = ViewBag.Title + " - " + Model.PageTitle;
}
But in the view the ViewBag.Title
is null. It does not cause an error but we end up with just " - MyPage" rather than "MySite - MyPage" for the browser title.
This all worked correctly in the previous version of .net, just not working now in ASP.NET Core. As I step through the debugger I see that the ControllerBase
constructor is being called but the ViewBag data is not persisting.
This leaves me with two questions:
Edit:
I set a debugger stop on the first line of the base controller and stepped through with the ViewBag.Title
set as my watch variable. As I step through I can see the value get set and then I move from the base controller to the constructor for the specific action controller. As I step through that constructor the ViewBag.Title
is still set. As soon as I hit the first line of the Index()
method the ViewBag.Title
turns to null
.
Edit2: Here is a simple foo project illustrating the issue https://github.com/nurdyguy/ViewBagIssue
Upvotes: 7
Views: 3374
Reputation: 2945
I still don't know why this is happening but here is a workaround I found. Create an OnActionExecuting
filter:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace MyProj.Filters
{
public class ViewBagFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// do something before the action executes
var controller = context.Controller as Controller;
controller.ViewBag.Title = "MyPage";
}
public void OnActionExecuted(ActionExecutedContext context)
{
// do something after the action executes
}
}
}
and add the following to the ConfigureServices
method in Startup.cs
:
services.AddMvc(options =>
{
options.Filters.Add(typeof(ViewBagFilter));
... // you may have more here...
});
You'll notice the var controller = context.Controller as Controller;
has a cast because the controller object on context
is an object
but it is easy enough to fix.
I'll post back here if I ever find out exactly what caused the issue to begin with. Good hunting!
Upvotes: 8