Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewData is not passed to layout in ASP.NET Core 2.1

Edited

I have an ASP.NET Core 2.1 website which I've scaffolded all of its Identity items. The scaffolding process created a layout file in this location:

/Areas/Identity/Pages/Account/Manage/_Layout.cshtml

As I wanted to use the layout globally, I have moved the layout file (with cut-paste) to this new location:

/Views/Shared/AdminLayout/_Layout.cshtml

Then created a _ViewStart.cshtml file in the first location to use the layout in the 2nd location. The content of _ViewStart file is this:

@{
    Layout = "/Views/Shared/AdminLayout/_Layout.cshtml";
    ViewData["ThisOneWorks"] = "some value";
}

Now the problem is, ViewDatas that I set from scaffolded pages (e.g. SetPassword.cshtml, ExtenalLogins.cshtml, ...) are not working in the layout file. For example ViewData["Title"] is always empty, but the ViewData that I've set in the _ViewStart is working.

The question is, How can I use ViewData from scaffolded identity files when I'm using a layout from the shared view folder?

Edit 1:

It seems the problem is with this line:

ViewData["ThisOneWorks"] = "some value";

When I remove it from the _ViewStart, all other ViewDatas work correctly, but why?

like image 764
Avestura Avatar asked Oct 03 '18 18:10

Avestura


People also ask

How do I pass a ViewData model?

To pass the strongly-typed data from Controller to View using ViewData, we have to make a model class then populate its properties with some data and then pass that data to ViewData dictionary as Value and selecting Key's name is the programmer's choice.

What is ViewData in ASP.NET Core?

In MVC, when we want to transfer the data from the controller to view, we use ViewData. It is a dictionary type that stores the data internally. ViewData contains key-value pairs which means each key must be a string in a dictionary. The only limitation of ViewData is, it can transfer data from controller to view.

How do I access ViewData?

The ControllerBase class has a ViewData dictionary property that can be used to populate data on controller and view. ViewData is a derivative of the ViewDataDictionary class, so you can access by the familiar "key/value" syntax, in other words it is a dictionary of objects that are accessible using strings as keys.


1 Answers

Well , it take me quite a lot of time to reproduce the same issue and debug . And finally , I find out it's a known bug .

  1. In which case will the bug occur ?

If you try to render a page that has an associated _ViewStart.cshtml , and if you set the ViewData within the ViewStart at the same time , the _Layout.cshtml will not render its ViewData correctly .

  1. The reason why it cannot work .

In short , the reason is that the ViewData within the Layout is the ViewContext.ViewData , instead of the this.ViewData that you set in your page . See the detailed explanation here

  1. Walkaround

The bug has been fixed in 2.2.0-preview1, and unfortunately there's no plan to fix it in 2.1.x. If you don't want to update your sdk , you can use the HttpContext.Items . Set Items in your RazorPage :

@{
    ViewData["Title"] = "Profile";                   // not working
    HttpContext.Items["Title"]="Workaround - Title"; // workaround
}

render Items in your _Layout:

<h1>@Context.Items["Title"]----render in layout</h1>
like image 131
itminus Avatar answered Sep 20 '22 19:09

itminus