Description
@davidfowl asked me for notes so here they are. You may want to scroll down to the pain points section below :)
Migration RC1 to RC2
Easy/expected changes:
Tools
install RC2 tooling.
The lastest tools can be found here: https://github.com/dotnet/cli
We first started with https://dotnet.github.io/getting-started/ but it's outdated.
global.json
Update version of global.json to match RC2
"version": "1.0.0-rc1-update1" // BEFORE
"version": "1.0.0-rc2-20221" // AFTER
Nuget.config
add ci builds to nuget config
<add key="AspNetCiDev" value="https://www.myget.org/F/aspnetcidev/api/v3/index.json" />
project.json
Dependencies
Update all dependencies from Microsoft.AspNet.xxx
to Microsoft.AspNetCore.xxx
except Microsoft.AspNet.WebApi.Client
Update all dependencies from x.EntityFramework.x
to x.EntityFrameworkCore.x
Downgrade version to 1.0 on all dependencies renamed.
Some package rename were by hand because it wasn't a straight convention,
Microsoft.AspNetCore.Diagnostics.Entity
Microsoft.EntityFrameworkCore.SqlServer
Some low-impact packages were removed:
Microsoft.VisualStudio.Web.BrowserLink.Loader
External dependency Moq
changed package name
"Moq": "", // BEFORE
"moq.netcore": "4.4.0-beta8", // AFTER
Frameworks
Update TFM. This change was a complete copy paste of some sample code. We had no idea what this change means.
before:
"frameworks": {
"dnx451": { },
"dnxcore50": { }
},
after:
"frameworks": {
"netcoreapp1.0": {
"imports": [ "dnxcore50", "portable-net45+win8" ]
}
},
Code Changes
NOTE: BEFORE
code may contain AspNetCore
because of the initial rename of all using
directive.
Usings
Rename all using directives in *.cs, *.cshtml
Find all and replace: using Microsoft.AspNet.
-> using Microsoft.AspNetCore.
About 122 occurrence(s).
Controllers
HttpNotFound // BEFORE 60 ocurrences
NotFound // AFTER
HttpBadRequest() // BEFORE 5 ocurrences
BadRequest() // AFTER
Entity Framework
GraphBehavior.X does not exist anymore on EF context methods.
using Microsoft.AspNetCore.Identity.EntityFramework; // BEFORE 2 ocurrences
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; // AFTER
using Microsoft.Data.Entity; // BEFORE 40 ocurrences
using Microsoft.EntityFrameworkCore; // AFTER
using Microsoft.Data.Entity.Metadata; // BEFORE 35 ocurrences
using Microsoft.EntityFrameworkCore.Metadata; // AFTER
using Microsoft.Data.Entity.Migrations; // BEFORE 47 ocurrences
using Microsoft.EntityFrameworkCore.Migrations; // AFTER
using Microsoft.Data.Entity.Infrastructure; // BEFORE 24 ocurrences
using Microsoft.EntityFrameworkCore.Infrastructure; // AFTER
_context.Phones.Add(phone, GraphBehavior.IncludeDependents); // SAMPLE
_context.Phones.Add(phone); // SAMPLE AFTER
Extensions
using Microsoft.AspNetCore.FileProviders; // AFTER 3 ocurrences
using Microsoft.Extensions.FileProviders; // BEFORE
using Microsoft.Extensions.OptionsModel; // BEORE 1 ocurrences
using Microsoft.Extensions.Options; // AFTER
Identity
User.GetUserId()
and User.IsSignedIn()
doesn't exist. it was removed and added to UserManager
and SignInManager
.
ExternalLoginInfo.ExternalPrincipal
was renamed to ExternalLoginInfo.Principal
User.GetUserId() // BEFORE 6 ocurrences
_userManager.GetUserId(User) // AFTER
User.IsSignedIn() // BEFORE 2 ocurrences
_signInManager.IsSignedIn(User) // AFTER
info.ExternalPrincipal // BEFORE
info.Principal // AFTER
Startup
services.AddEntityFramework()
.AddSqlServer() // BEFORE
services.AddEntityFrameworkSqlServer()
.AddEntityFrameworkSqlServer() // AFTER
services.AddCaching(); // NOT FOUND ??? REMOVED
app.UseDatabaseErrorPage(); // NOT FOUND ??? REMOVED
app.UseRequestLocalization(
new RequestCulture(
new CultureInfo("en-us"))); // BEFORE
app.UseRequestLocalization(
new RequestLocalizationOptions() {
DefaultRequestCulture = new RequestCulture(
new CultureInfo("en-us")) }); // AFTER
app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear()); // NEED MORE INVESTIGATION. OPTIONS REMOVED.
This change is a complete copy/paste from sample. No idea what's going on here.
// Entry point for the application. BEFORE
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
// Entry point for the application. AFTER
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseDefaultHostingConfiguration(args)
.UseIIS()
.UseStartup<Startup>()
.Build();
host.Run();
}
## Pain points: ### DotNet Restore
This was executed multiple times, at different point of migration.
Mostly all the output was kinda useless. Too much information, to many unknowns.
We tried to switch to -v warning with no luck.
It took some time to get to -v Minimal to get a usefull output from dotnet restore.
App Settings
We found a runtime Error with regarding appsettings. The error was clear, the options available not.
The fix was to change Verbose to Information
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Information", // BEFORE: "Verbose"
"System": "Information",
"Microsoft": "Information"
}
}
We used POCO Configuration with code like:
services.Configure<StorageSettings>(Configuration.GetSection("StorageSettings"));
we dig into lots of documents, code, issues.
We hope this would be on Announcements repo but we couldn't find it.
we ended up with a hack
services.Configure<StorageSettings>(x => x.ConnectionString = Configuration["StorageSettings:ConnectionString"]);
Code
Some inner workings of razor,views,engines,etc changes weren't mentioned anywhere.
We have a simple taghelper that render partial views, this was impossible to figure out how to update it.
NTaylorMullen helped there.
Compile success!
Great, right... right?
Environment
Visual Studio environment variable wasn't respected. We first thought that ConfigureDevelopment
were removed.
The problem here was that dotnet run shows the enviroment but an error was throw before.
Also this environment variable was changed twice for RC2. The announcement issue shows the old one with a note at the bottom that was changed again.
We wasted lot of time dealing with environment. mostly because of not understading the problem straight.
cshtml
@Inject namespaces had to be renamed,
taghelpers, etc.
because this was after hitting a specific page it was more painful than the cs code.
we also lost intellisense so... we had to rely on error messages.
tooling
We literally copy pasted every tooling sample until we got this:
"tools": {
"dotnet-publish-iis": "1.0.0-*",
"dotnet-ef": "1.0.0-*",
"dotnet-watch": "1.0.0-*",
"dotnet-razor-tooling": "1.0.0-*"
},
We still have no idea how those exactly works.
The only one that was really needed was EF because migrations (see next point).
We tried for several hours to get dotnet-watch
to run without success.
EF Changes
I hit this issue: Invalid object name 'TableName'
before an announcement were created here:
EF Core: Table names now taken from DbSet names (starting in RC2).
While it was a simple ask repo and got a solution very quickly, it was like a neverending error trip.
At this point we were tired.
... And runs! ..., almost
we hit the web application but we seen no static files served!
DAMN!
We looked everywhere until we figure out that no gulp build was executed! even we had that on prepublish
.
and well.. then