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
To pass the strongly typed data from Controller to View using ViewBag, we have to make a model class then populate its properties with some data and then pass that data to ViewBag with the help of a property. And then in the View, we can access the data of model class by using ViewBag with the pre-defined property.
Yes you cannot pass a Viewbag from view to controller. But you can pass them using TempData.
ViewBag is a dynamic property that takes advantage of the new dynamic features in C# 4.0. ViewData requires typecasting for complex data type and check for null values to avoid error. ViewBag doesn't require typecasting for complex data type.
The Microsoft Developer Network writes that the ViewBag property allows you to share values dynamically to the view from the controller. As such, it is considered a dynamic object without pre-set properties.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With