Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Unable to set ViewBag or ViewData entries from Controller constructors #1422

@dougbu

Description

@dougbu

The following works in MVC 5.2 but throws an InvalidOperationException in vNext. This prevents common initialization scenarios unless the user is aware of OnActionExecuting() or OnActionExecutionAsync() (which are less discoverable than MVC 5.2's Initialize() method). ViewData["Items"] doesn't help because ViewData is null.

public class HomeController : Controller
{
  private static readonly IEnumerable<SelectListItem> _items =
    new SelectList(Enumerable.Range(7, 13));

  public HomeController()
  {
    ViewBag.Items = _items;
  }
  ...
}

Details:
The root cause is DefaultControllerActivator creates the controller's ViewDataDictionary instance. So ViewData is null until Controller instances are activated. Worse if ViewBag is used while ViewData is still null, the result is an InvalidOperationException thrown from the DynamicViewData.ViewData getter.

By contrast, few properties in the MVC 5.2 Controller class even return null (let alone throw) if invoked from the constructor. (Exceptions include ControllerContext, Url, and anything ControllerContext-derived e.g. HttpContext and User. All of those simply return null prior to the Initialize() call.)

Probably need to revisit the Controller activation model. At least should look at the properties lazy-initialized in MVC 5.2 and decide if they should be handled similarly in vNext.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions