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

2

6

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?

Gennagennaro answered 3/10, 2018 at 18:27 Comment(3)
Is the code in a public repo?Rousseau
Have you tried with an index string without exclamation mark (!) e.g. ViewData["Title"]Eldred
@MohsinMehmood Yes, that is only a sample in the SO question. I use another index string in the code and it only has English chars.Gennagennaro
W
6

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>
Weeny answered 5/10, 2018 at 2:41 Comment(1)
Here it seems to work with ViewContext.ViewData[], not ViewData or HttpContext.ViewData.ItemsBullring
W
0

Please use the ViewData Attribute if you want to pass it to the Layout

[ViewData]
public string Title {get; set;}
Whortleberry answered 14/1 at 1:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.