The Error
You're building/running your ASP.NET Core app and get hit with:
Error CS1061: 'HomeController' does not contain a definition for 'ViewBag' and no accessible extension method 'ViewBag' accepting a first argument of type 'HomeController' could be found
Or the runtime version:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Text.Json.JsonElement' does not contain a definition for 'Name'
Screenshot: Red squiggly under ViewBag in VS 2022, build fails with 1 error.
TL;DR - 30 Second Fix
For MVC: Your controller must inherit Controller, not ControllerBase. Change public class HomeController : ControllerBase to public class HomeController : Controller.
For API/Minimal API: You're trying to use ViewBag in an API. APIs don't have views. Return Results.Ok(data) or Ok(data) instead.
For dynamic JSON: Use obj.GetProperty("Name").GetString() not obj.Name.
Why This Happens - Root Cause
CS1061 means the C# compiler looked for a property/method on your object and couldn't find it. In ASP.NET Core 8, there are 3 main causes:
- Wrong base class - 70% of cases:
ControllerBaseis for APIs. It has noViewBag,ViewData, orTempData.Controllerinherits fromControllerBaseand adds MVC view features. New devs copy API controller templates for MVC projects. - Breaking change in.NET 6+:
System.Text.JsonreturnsJsonElementfor dynamic objects.JsonElementdoesn't have properties. You must useGetProperty(). Old Newtonsoft.Json alloweddynamic.Name. - Missing using or package: Extension methods like
HttpContext.SessionneedMicrosoft.AspNetCore.Http. If you targetnet8.0without ASP.NET SDK, those extensions vanish.
.NET 8 Specific: Minimal APIs are now the default template. Scaffolding a "Controller" in a Minimal API project gives you ControllerBase. Microsoft assumes you don't need views.
Solution 1: Quick Fix - MVC ViewBag/ViewData - 1 Min
Step 1: Open your controller file.
// WRONG
public class HomeController : ControllerBase
{
public IActionResult Index()
{
ViewBag.Title = "Home"; // CS1061
return View();
}
}
Step 2: Change the inheritance:
// RIGHT
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
public IActionResult Index()
{
ViewBag.Title = "Home"; // Works
ViewData["User"] = "John";
TempData["Msg"] = "Saved";
return View();
}
}
Why it works: Controller class contains public dynamic ViewBag { get; }. ControllerBase does not.
Solution 2: Proper Fix - API Controllers Shouldn't Use ViewBag - 5 Min
If you're building an API, ViewBag is a code smell. APIs return data, not HTML.
Step 1: Remove ViewBag, return models:
// WRONG for API
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
public IActionResult Get()
{
ViewBag.Count = 10; // CS1061 + wrong pattern
return Ok();
}
}
// RIGHT for API
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
public ActionResult<UserDto> Get()
{
var dto = new UserDto { Count = 10, Users = _repo.GetAll() };
return Ok(dto); // Serializes to JSON
}
}
Step 2: If you really need views + API, use Controller not ControllerBase, or split into 2 controllers.
Production tip: Add [ProducesResponseType(200, Type = typeof(UserDto))] for Swagger docs.
Solution 3: System.Text.Json Dynamic Access - 2 Min
Used JsonSerializer.Deserialize<dynamic> or got JsonElement from API?
// WRONG - CS1061
var json = JsonSerializer.Deserialize<dynamic>(str);
string name = json.Name; // RuntimeBinderException
// RIGHT - System.Text.Json
var json = JsonSerializer.Deserialize<JsonElement>(str);
string name = json.GetProperty("Name").GetString();
// RIGHT - If you control the class
public class User { public string Name { get; set; } }
var user = JsonSerializer.Deserialize<User>(str);
string name = user.Name; // Works, strongly typed
.NET 8 Tip: Use [JsonPropertyName("name")] if JSON is camelCase.
Common Variations
1. CS1061 in Razor Pages
Razor Pages use PageModel. No ViewBag. Use public string Title { get; set; } property and @Model.Title in.cshtml.
public class IndexModel : PageModel
{
public string Title { get; set; }
public void OnGet() => Title = "Home";
}
2. CS1061 in Blazor
Blazor components don't have ViewBag. Use [Parameter] or inject services. For "TempData" pattern use ProtectedSessionStorage.
3. CS1061 after upgrading to.NET 8
Check your .csproj. If you changed <Project Sdk="Microsoft.NET.Sdk.Web"> to Microsoft.NET.Sdk, you lose ASP.NET extensions. Revert to Web SDK.
How to Prevent This Error
- Use correct template:
dotnet new mvcnotdotnet new webapiif you need views. - Enable analyzers:
<AnalysisMode>AllEnabledByDefault</AnalysisMode>in csproj warns about ControllerBase misuse. - Avoid dynamic: Strong types >
dynamic. Userecordfor DTOs. - CI check:
dotnet build -warnaserrorfails build on CS1061.
Related Errors You Might Hit Next
- Cannot consume scoped service from singleton - Happens when you inject DbContext wrong
- CORS with credentials error - Next error after fixing API returns
- Razor Pages handler not found 404 - If you switch to Razor Pages
- No service for type IControllerFactory - Missing AddControllers()
FAQ - Featured Snippet Targets
Q: Does ViewBag work in.NET 8?
Yes, but only if your controller inherits from Microsoft.AspNetCore.Mvc.Controller. It does NOT work with ControllerBase, Minimal APIs, or Razor Pages.
Q: Should I use ViewBag or ViewData?
Neither for new code. Use strongly-typed ViewModels: return View(model). ViewBag is dynamic and not refactor-safe. ViewData is a dictionary. Both are slower.
Q: Can I use ViewBag in an API Controller?
No. APIs return JSON/XML, not HTML views. ControllerBase has no ViewBag. If you need both API + views, create separate controllers or use Controller base class.
Q: Why did this break after upgrading from.NET Framework?
ASP.NET Core split Controller into ControllerBase + Controller. Old MVC controllers implicitly had ViewBag. New ones need explicit : Controller.
Still stuck? Message me on LinkedIn with your exact error +.NET version. I reply to devs in 24hrs.
Author: DevFix Team - Shipped 200+ ASP.NET Core fixes since 2022. Code tested on.NET 8.0.100 + Windows + Linux Docker.
No comments yet. Be the first to share your thoughts!