_From @karelz on May 10, 2018 17:37_
_From @hez2010 on May 8, 2018 4:33_
I use .NET Core 2.1.300-rc1 to create a new MVC web app with individual authentication, then I use identity scaffolder (visual studio -> right click my project -> add -> new scaffolded item -> identity) and specify layout file with "~/Views/Shared/_Layout.cshtml" to generate identity related code in Areas/Identity automatically.
When I try to build, the compiler warns me that I need to use \
And then I run the website, when I navigated to Login/Register page in browser, I found that the _LoginPartial View could not be loaded correctly that it still remained \\ but not \\ in HTML source so that I could not click Login or Register again. Also, I changed the navbar style in _LoginPartial.cshtml but when I navigated to Login/Register page, it restored to original styles.
Normally (in home page):

In Login/Register page:

But after I changed the code in _Layout.cshtml:
\

Hope that you can fix this bug, thanks!
_Copied from original issue: dotnet/corefx#29566_
_Copied from original issue: aspnet/Mvc#7768_
_From @karelz on May 10, 2018 17:37_
_From @kasper3 on May 8, 2018 7:12_
this belongs to https://github.com/aspnet/razor or https://github.com/aspnet/mvc
_From @pranavkm on May 10, 2018 17:49_
@javiercn does scaffolding need to be updated?
_From @hez2010 on May 10, 2018 17:56_
I found a new bug.
the scaffolder will ignore the layout file which user specified and keeps ~/Areas/Identity/Pages/Account/Manage/_Layout.cshtml 's layout file as "/Areas/Identity/Pages/_Layout.cshtml" despite the file /Areas/Identity/Pages/_Layout.cshtml doesn't exist.
@seancpeters Is this fixed in RTM with your changes?
@javiercn - I created a MVC individual auth project using:
"Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.0-rtm-30762"
There are multiple issues mentioned in this thread, I'll try to address them all:
The _Layout.cshtml includes <partial name="_LoginPartial" />
I can navigate corerctly between the Register & Login pages. The source of the login page and the register page includes:

I'm not clear what this is trying to point out:
the scaffolder will ignore the layout file which user specified and keeps ~/Areas/Identity/Pages/Account/Manage/_Layout.cshtml 's layout file as "/Areas/Identity/Pages/_Layout.cshtml" despite the file /Areas/Identity/Pages/_Layout.cshtml doesn't exist.
Can yiou help me understand this part?
@seancpeters I mean that after scaffolding, the layout file of /Areas/Identity/Pages/Account/Manage/_Layout.cshtml should be ~/Views/Shared/_Layout.cshtml, but actually it is /Areas/Identity/Pages/_Layout.cshtml.
you can see my commit: https://github.com/hez2010/hjudgeNEW/commit/9f7dbe482d202fa8683d44a36328d5e89c59ab2d#diff-7826a144e5b74bb0e26273eaf58194d4
In order to fix it manually, I changed Layout = "/Areas/Identity/Pages/_Layout.cshtml"; to Layout = "~/Views/Shared/_Layout.cshtml";
This is correctly now correctly dealt with - the user specified layout file is respected.
@seancpeters I also I used .NET Core 2.1.300-rc1 to create a new MVC web app with individual authentication, then I used identity scaffolder, but did not specify a layout file, just left it blank and then let it generate the identity related code in Areas/Identity.
The scaffolded Identity UI seems to be a bunch of Razor Pages , so when viewing the Identity UI, the Layout will be switched over to the layout specified in /Pages/Shared/_Layout.cshtml rather than /Views/Shared/_Layout.cshtml which is for the main part of the app which consists of MVC pages.
@javiercn I also noticed that inside the file:
~/Areas/Identity/Pages/Account/Manage/_Layout.cshtml
Layout = "/Areas/Identity/Pages/_Layout.cshtml";
That file does not exist, but the logout button still shows when viewing the account management pages. The issue is that the Logout button does not work, it posts to the current page (/Identity/Account/Manage) resulting in a 400 bad request.
Looking at the page source, it seems that the _LoginPartial.cshtml razor page has not been rendered properly as the 'asp-' tags are visible in the html source like this:
<form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnurl="/?page=%2FIndex" method="post" id="logoutForm" class="navbar-right">
It should look like this as it does from the Home/Index page:
<form method="post" id="logoutForm" class="navbar-right" action="/Identity/Account/Logout?returnUrl=%2F">
This means that out of the box, the scaffolded Identity UI does not work properly, the logout button only works from outside of the account management pages, ie. from the MVC views. Once inside the Razor Pages, the Logout button is broken.
I have tried various things:
I have confirmed that the "/Pages/Shared/_Layout.cshtml" file is actually being used despite what is specified in the area layout file as i changed the "Logout" button text inside "/Pages/Shared/_LoginPartial.cshtml" and could see the updated text when inside the account management pages.
After reading:
https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-2.1
I went into "/Pages/Shared/_Layout.cshtml" , I changed line 41 from:
await Html.RenderPartialAsync("_LoginPartial");
to
await Html.PartialAsync("_LoginPartial");
thinking that may be why the LoginPartial.cshtml is not being rendered properly, but it made no difference.
After reading the linked issue:
https://github.com/aspnet/Mvc/issues/7768
I tried changing it to:
await Html.PartialAsync("_LoginPartial.cshtml");
and
await Html.RenderPartialAsync("_LoginPartial.cshtml");
and
<partial name="_LoginPartial" />
and
<partial name="_LoginPartial.cshtml" />
again no difference.
I am not sure if this issue should sit here or with Razor?
To try and get it to work i ditched the 'asp-' tags and changed the form inside _LoginPartial.cshtml to:
<form action="/Identity/Account/Logout?returnUrl=%2F" method="post" id="logoutForm" class="navbar-right">
The Logout button now correctly posts to /Identity/Account/Logout, but i still get a 400 bad request and the OnPost method in the Logout.cshtml.cs file is not being fired. Looking at the Chrome inspector, the form post looks identical to the one from the Home/Index page which works fine.
Looking at the network requests they are also identical, the one from Home/Index works fine and procuces a 302 redirect to '/' The one from /Identity/Account/Manage produces a 400 bad request and does not fire the OnPost method. I think this needs a fresh pair of eyes so ill come back to it another day, almost midnight in the UK.
I have had chance to take another look at this and found out why i can logout successfully from the root fo the site but not from the account management UI (/Identity/Account/Manage).
The source of the root home page contains a RequestVerificationToken in the html body inside the "logoutForm" element:
<form method="post" id="logoutForm" class="navbar-right" action="/Identity/Account/Logout?returnUrl=%2F">
<ul class="nav navbar-nav navbar-right">
<li>
<a title="Manage" href="/Identity/Account/Manage">Hello [email protected]!</a>
</li>
<li>
<button type="submit" class="btn btn-link navbar-btn navbar-link">Logout</button>
</li>
</ul>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8DxKt2Y1qMpIpID........" />
</form>
When the form is Posted to /Identity/Account/Logout, the token is sent in the request body:
__RequestVerificationToken=CfDJ8DxKt2Y1qMpIpID........
However the /Identity/Account/Manage page contains the same logout form but without the RequestVerificationToken token:
<form action="/Identity/Account/Logout?returnUrl=%2F" method="post" id="logoutForm" class="navbar-right">
<ul class="nav navbar-nav navbar-right">
<li>
<a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello [email protected]!</a>
</li>
<li>
<button type="submit" class="btn btn-link navbar-btn navbar-link">Logout me</button>
</li>
</ul>
</form>
So the Post to /Identity/Account/Logout does not contain the token, resulting in a failed request.
This can be seen in the output log which i failed to notice at first:
info: Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.AutoValidateAntiforgeryTokenAuthorizationFilter[1]
Antiforgery token validation failed. The required antiforgery request token was not provided in either form field "__RequestVerificationToken" or header value "RequestVerificationToken".
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The required antiforgery request token was not provided in either form field "__RequestVerificationToken" or header value "RequestVerificationToken".
It looks like the token is automatically added to forms as there is no attribute or code in the scaffolded files or the MVC template file which specifically adds it.
As mentioned in my previous post, the original issue is that the /Pages/Shared/_LoginPartial.cshtml razor page is not being rendered correctly preventing the logout from working, so as a quick hack to get it to work until this is fixed i added the form action manually.
The missing RequestVerificationToken in the form html is probably because the _LoginPartial.cshtml is not being rendered correctly. Maybe this can be manually added but it's going to get a bit too hacky, i hope this will be fixed before RTM.
The _LoginPartial.cshtml has existed in /View/Shared/, but the scaffolder still created one in /Pages/Shared/
After deleting /Pages/Shared/_LoginPartial.cshtml, the problem I mentioned above was gone.
Deleting /Pages/Shared/_LoginPartial.cshtml has indeed solved the above problem, thanks!
However now when i click the 'Login' link i get this:
InvalidOperationException: The partial view '_LoginPartial.cshtml' was not found. The following locations were searched:
/Pages/Shared/_LoginPartial.cshtml
So i tried also removing /Pages/Shared/_Layout.cshtml but also get an exception with cant find the _Layout.cshtml file.
In both cases the Register and Login links are there, as they are coming from the Views/Shared folders when looking at the MVC root. However when clicking on the Login link it loads the Razor pages which will presumably use /Pages/Shared/ so results in the error. For some reason when i was already signed in after deleting the file and looking at the account management UI, the Logout link was there and worked, despite the Pages/Shared/_LoginPartial.cshtml being deleted.
You may also need to change the code in /Areas/Identity/Pages/_ViewStart.cshtml, replacing "/Pages/Shared/_Layout.cshtml" with "~/Views/Shared/_Layout.cshtml"
@chrisckc
@hez2010 That did the trick thanks, didn't know that it was ok to share the MVC view layouts with the Razor Pages as the Identity scaffolder created separate /Pages/Shared/ layouts so i figured there was a valid reason that the scaffolder did that.
For what i want i prefer to share the base MVC layout, but it looks like if you did want to use a separate layout for the Razor pages it is not currently possible due to an issue rendering the 'Razor Pages' layout files.
The issue is now resolved for the evaluation i was performing, but there is a major issue with the Identity Scaffolder as it does not produce a working set of files. Everything works ok until you run the Identity Scaffolder, after that you are unable to logout from within the account management pages.
There were no options available in the scaffolder to get this right from the start, the only options are _"Select and existing layout page, or specify a new one"_ but this seems to be referring to the layout which adds the left side navigation menu within the account management pages, not the master layout which includes the top nav menu and Login/Logout/Register links.
Also in the scaffolder, there is no way to select an existing or add a new custom user subclass, the selection box is greyed out, but i can select the data context class. This meant that i had to manually update all of the the scaffolded files with a search and replace to use the custom user subclass.
Btw. I am using Visual Studio 15.7.1 on Windows
@chrisckc - If you choose to create a new data context class, the User Class selector becomes active, and the new data context class will use the newly created user class.
When selecting an existing data context class, it's not possible to add a new user class - the existing data context class was already setup with either an existing custom user class, or the default IdentityUser.
Also notice that ViewData["Title"] in /Pages/Shared/_Layout.cshtml doesn't update while browsing Identity pages. You can set a permanent title e.g. ViewData["Title"] = "Profile"; in /Pages/Account/Manage/_Layout.cshtml But before you can even begin to make changes in Identity pages you need to do what hez2010 said, by changing Layout to /Pages/Shared/_Layout.cshtml.
Still was not fixed. When I scaffold Identity pages in Blazor project face with the same problem.
Two years have gone already, Microsoft really?????
Most helpful comment
@seancpeters I also I used .NET Core 2.1.300-rc1 to create a new MVC web app with individual authentication, then I used identity scaffolder, but did not specify a layout file, just left it blank and then let it generate the identity related code in Areas/Identity.
The scaffolded Identity UI seems to be a bunch of Razor Pages , so when viewing the Identity UI, the Layout will be switched over to the layout specified in /Pages/Shared/_Layout.cshtml rather than /Views/Shared/_Layout.cshtml which is for the main part of the app which consists of MVC pages.
@javiercn I also noticed that inside the file:
~/Areas/Identity/Pages/Account/Manage/_Layout.cshtml
Layout = "/Areas/Identity/Pages/_Layout.cshtml";That file does not exist, but the logout button still shows when viewing the account management pages. The issue is that the Logout button does not work, it posts to the current page (/Identity/Account/Manage) resulting in a 400 bad request.
Looking at the page source, it seems that the _LoginPartial.cshtml razor page has not been rendered properly as the 'asp-' tags are visible in the html source like this:
<form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnurl="/?page=%2FIndex" method="post" id="logoutForm" class="navbar-right">It should look like this as it does from the Home/Index page:
<form method="post" id="logoutForm" class="navbar-right" action="/Identity/Account/Logout?returnUrl=%2F">This means that out of the box, the scaffolded Identity UI does not work properly, the logout button only works from outside of the account management pages, ie. from the MVC views. Once inside the Razor Pages, the Logout button is broken.
I have tried various things:
I have confirmed that the "/Pages/Shared/_Layout.cshtml" file is actually being used despite what is specified in the area layout file as i changed the "Logout" button text inside "/Pages/Shared/_LoginPartial.cshtml" and could see the updated text when inside the account management pages.
After reading:
https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-2.1
I went into "/Pages/Shared/_Layout.cshtml" , I changed line 41 from:
await Html.RenderPartialAsync("_LoginPartial");to
await Html.PartialAsync("_LoginPartial");thinking that may be why the LoginPartial.cshtml is not being rendered properly, but it made no difference.
After reading the linked issue:
https://github.com/aspnet/Mvc/issues/7768
I tried changing it to:
await Html.PartialAsync("_LoginPartial.cshtml");and
await Html.RenderPartialAsync("_LoginPartial.cshtml");and
<partial name="_LoginPartial" />and
<partial name="_LoginPartial.cshtml" />again no difference.
I am not sure if this issue should sit here or with Razor?
To try and get it to work i ditched the 'asp-' tags and changed the form inside _LoginPartial.cshtml to:
<form action="/Identity/Account/Logout?returnUrl=%2F" method="post" id="logoutForm" class="navbar-right">The Logout button now correctly posts to /Identity/Account/Logout, but i still get a 400 bad request and the OnPost method in the Logout.cshtml.cs file is not being fired. Looking at the Chrome inspector, the form post looks identical to the one from the Home/Index page which works fine.
Looking at the network requests they are also identical, the one from Home/Index works fine and procuces a 302 redirect to '/' The one from /Identity/Account/Manage produces a 400 bad request and does not fire the OnPost method. I think this needs a fresh pair of eyes so ill come back to it another day, almost midnight in the UK.