Having discovered that .NET Core 2.2 has been released I decided to have a look what has changed in the MVC & "Identity UI" templates created using dotnet new mvc
and the aspnet code generator.
To find out what's new in ASP.NET Core 2.2, read this: https://docs.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-2.2?view=aspnetcore-2.2
I first created a new project using dotnet new mvc
and compared it to one generated using 2.1.
The first thing that is noticed when running the project is a new look for the template app:
This is due to the fact that the views have been updated to use Bootstrap v4 and have been cleaned up to remove the marketing clutter from the home page that existed in 2.1.
Apart from the changes to the views and removal of the unneeded actions from HomeController, the only other visible code changes are in Startup.cs:
The mvc compatibility version:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
A comment about HSTS:
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
Changes to Identity Scaffolding
Adding Identity scaffolded files
As I had previously installed the aspnet code generator under 2.1, I first updated it:
dotnet tool update --global dotnet-aspnet-codegenerator
Tool 'dotnet-aspnet-codegenerator' was successfully updated from version '2.1.6' to version '2.2.0'.
Then ran the code generator to generate the Identity scaffolding:
dotnet-aspnet-codegenerator Identity
Scaffolding failed. Please add Microsoft.VisualStudio.Web.CodeGeneration.Design package to the project as a NuGet package reference.
So I did what it said and added this to the csproj file:
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2" PrivateAssets="All" />
dotnet restore
Ran the code generator again:
dotnet-aspnet-codegenerator Identity
Building project ... Finding the generator 'Identity'... Running the generator 'Identity'... RunTime 00:00:12.66
Which resulted in the usual 'Areas' directory being added, along with a connection string for SQL server, the same as what was done by the previous code generator.
I am surprised that the 2.1 and 2.2 code generators specify SQL server, given the cross platform nature of .NET Core. This was a change from 2.0 which specified SQLite.
Finally, follow the instructions in generated "ScaffoldingReadme.txt" before running the app for the first time.
Running the app
Running the app again with the Identity scaffolding added revealed an issue, there was no "Register" or "Login" link in the nav bar. The file "Views/Shared/_LoginPartial.cshtml" has been added but "Views/Shared/_Layout.cshtml" had not been updated.
Maybe this was because I didnt use the '--force' option on the generator to force it to update existing files, this was sometimes required in the previous version, but a warning was issued if it was needed.
Ran the code generator again with --force:
dotnet-aspnet-codegenerator Identity --force
No luck, _Layout.cshtml still not updated.
So it looks like there is an issue in the code generator. This is easily be fixed by adding the partial to _Layout.cshtml, right after the navbar markup:
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
..............
</div>
<partial name="_LoginPartial" />
Now it looks better:
However it does not look correct on a small screen, placing the partial in the navbar as shown here sorts that out:
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav">
<partial name="_LoginPartial" />
</ul>
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
The above html was obtained by looking at the non-scaffolded UI output.
Logged an issue for that: "Views/Shared/_Layout.cshtml not updated when scaffolding Identity in 2.2 release" https://github.com/aspnet/Scaffolding/issues/931
Comparison between 2.2 and 2.1 Identity scaffolding
Looking at the scaffolded Identity code there are no real changes to the code, just changes to the views to bring them inline with Bootstrap v4.
Inside the most of the scaffolded Identity views, the titles have been changed from h2 to h1
<h1>@ViewData["Title"]</h1>
The bootstrap buttons have been changed to btn-primary:
<button type="submit" class="btn btn-primary">Submit</button>
Some view have had id's added to some elements, in Login.cshtml, id has been added to the form:
<form id="account" method="post">
The account management sidebar nav has been updated to Bootstrap v4 but looks like it's been a rushed job:
The most obvious issue is that the top navbar style does not match the style of the MVC app. The nav menu is very basic and does not properly stack vertically, the profile and logout links in the top nav bar are also out of alignment.
The small screen layout also has alignment issues:
Non-scaffolded Identity UI
Creating a non-scaffolded Identity project using:
dotnet new mvc --auth Individual
reveals that this is only an issue with the scaffolded UI produced by the code generator.
Here is how the non-scaffolded Identity UI looks, this is better:
I also noticed that the non-scaffolded project still uses SQLite and also contains a new option which i haven't seen used before: ".AddDefaultUI(UIFramework.Bootstrap4)"
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
Summary
The update to bootstrap 4 is long overdue, however there are some mismatches between the default UI and the scaffolded UI which need to be resolved.
The out-of-the-box styling issues with the scaffolded UI would be a bit of a disappointment if the intention was to use it as a base to customise it further.
UPDATE: I tried adding .AddDefaultUI(UIFramework.Bootstrap4) from the above code and the UI now looks correct. I am still able to override the UI by editing the scaffolded files, so there must be some merging going on somewhere. It still needs _Layout.cshtml to be updated by adding _LoginPartial.cshtml to get the Login and Register links working.
FURTHER UPDATE: After a little more investigation it seems that the most elegant and obvious solution is to change the reference in "Areas/Identity/Pages/Account/Manage/_Layout.cshtml" to point to the main layout file, in the case of an MVC app, change the reference at the top of the file to this:
@{
Layout = "/Views/Shared/_Layout.cshtml";
}
By default it points to a _Layout file which does not exist in the scaffolded files, it is instead provided by the Identity UI library, it really should be generated by the scaffolder to allow it to be customised as that is the whole point of scaffolding all of the files, refer to this issue: https://github.com/aspnet/Scaffolding/issues/884
Looking at the generated html in the browser dev tools revealed that the missing scaffolded _Layout file must be almost identical to the main _Layout file.
This is the best solution as you will also retain the links in the main app navbar when viewing the account management pages and there is only a single layout to maintain, this should also be the default setup provided by the scaffolder