DEV Community

Masui Masanori
Masui Masanori

Posted on

[ASP.NET Core][EntityFramework Core] Update from .NET 5 to .NET 6

Intro

Congratulations on the release of .NET 6 !
I want to update ASP.NET Core projects what are made in .NET 5 to .NET 6.

Environments

  • .NET ver.5.0.202 -> .NET ver.6.0.100

Sample project

I use a project what I created for trying signing in from Blazor pages.

ApprovementWorkflowSample.csproj

<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="NLog.Web.AspNetCore" Version="4.10.0"/> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.2"/> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2"/> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.2"/> <PackageReference Include="Newtonsoft.Json" Version="12.0.3"/> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.2"/> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.2"/> </ItemGroup> </Project> 
Enter fullscreen mode Exit fullscreen mode

Program.cs

using System; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using NLog.Web; namespace ApprovementWorkflowSample { public class Program { public static void Main(string[] args) { var logger = NLogBuilder.ConfigureNLog("Nlog.config").GetCurrentClassLogger(); try { CreateHostBuilder(args).Build().Run(); } catch (Exception ex) { logger.Error(ex, "Stopped program because of exception"); throw; } finally { NLog.LogManager.Shutdown(); } } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .ConfigureLogging((hostingContext, logging) => { logging.ClearProviders(); logging.SetMinimumLevel(LogLevel.Trace); }) .UseNLog(); } } 
Enter fullscreen mode Exit fullscreen mode

Startup.cs

using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using ApprovementWorkflowSample.Applications; using ApprovementWorkflowSample.Models; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Server; using ApprovementWorkflowSample.Approvements; namespace ApprovementWorkflowSample { public class Startup { private readonly IConfiguration configuration; public Startup(IConfiguration configuration) { this.configuration = configuration; } public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddServerSideBlazor(); services.AddHttpClient(); services.AddControllers() .AddNewtonsoftJson(); services.AddDbContext<ApprovementWorkflowContext>(options => options.UseNpgsql(configuration["DbConnection"])); services.AddIdentity<ApplicationUser, IdentityRole<int>>() .AddUserStore<ApplicationUserStore>() .AddEntityFrameworkStores<ApprovementWorkflowContext>() .AddDefaultTokenProviders(); services.AddScoped<IHostEnvironmentAuthenticationStateProvider>(sp => (ServerAuthenticationStateProvider) sp.GetRequiredService<AuthenticationStateProvider>() ); services.AddScoped<IApplicationUsers, ApplicationUsers>(); services.AddScoped<IWorkflows, Workflows>(); services.AddScoped<IApplicationUserService, ApplicationUserService>(); services.AddScoped<IApprovementService, ApprovementService>(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapControllers(); }); } } } 
Enter fullscreen mode Exit fullscreen mode

Update to .NET 6

To update the project to .NET 6, I change "ApprovementWorkflowSample.csproj" first.

ApprovementWorkflowSample.csproj

<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0"/> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.1"/> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0"/> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0"/> <PackageReference Include="Newtonsoft.Json" Version="13.0.1"/> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.0"/> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.0"/> </ItemGroup> </Project> 
Enter fullscreen mode Exit fullscreen mode

Before .NET 5 or earlier, I had had to changed some code after restoring.
But in this time, I don't need to change anything.

Merge "Startup.cs" into "Program.cs"

If I create a new .NET 6 project, it doesn't have "Startup.cs" and "Program.cs" doesn't have a class.

Program.cs (mvc template)

var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); 
Enter fullscreen mode Exit fullscreen mode

Program.cs

using ApprovementWorkflowSample.Models; using ApprovementWorkflowSample.Applications; using ApprovementWorkflowSample.Approvements; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Server; using NLog.Web; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; var logger = NLogBuilder.ConfigureNLog("Nlog.config").GetCurrentClassLogger(); try { var builder = WebApplication.CreateBuilder(args); builder.Host.ConfigureLogging(logging => { logging.ClearProviders(); logging.AddConsole(); }) .UseNLog(); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddHttpClient(); builder.Services.AddControllers() .AddNewtonsoftJson(); builder.Services.AddDbContext<ApprovementWorkflowContext>(options => options.UseNpgsql(builder.Configuration["DbConnection"])); builder.Services.AddIdentity<ApplicationUser, IdentityRole<int>>() .AddUserStore<ApplicationUserStore>() .AddEntityFrameworkStores<ApprovementWorkflowContext>() .AddDefaultTokenProviders(); builder.Services.AddScoped<IHostEnvironmentAuthenticationStateProvider>(sp => (ServerAuthenticationStateProvider) sp.GetRequiredService<AuthenticationStateProvider>() ); builder.Services.AddScoped<IApplicationUsers, ApplicationUsers>(); builder.Services.AddScoped<IWorkflows, Workflows>(); builder.Services.AddScoped<IApplicationUserService, ApplicationUserService>(); builder.Services.AddScoped<IApprovementService, ApprovementService>(); // I can't do this before setting "WebApplicationBuilder". var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapControllers(); }); app.Run(); } catch (Exception ex) { logger.Error(ex, "Stopped program because of exception"); } finally { NLog.LogManager.Shutdown(); } 
Enter fullscreen mode Exit fullscreen mode

DateTime (EntityFramework Core + Npgsql)

From .NET 6, the data types of date and time have been changed.

And I got an exception when I insert data.

ApplicationUser.cs

using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.AspNetCore.Identity; namespace ApprovementWorkflowSample.Applications { public class ApplicationUser: IdentityUser<int> { ... [Required] [Column("last_update_date", TypeName = "timestamp with time zone")] public DateTime LastUpdateDate { get; set; } ... public void Update(string userName, string? organization, string email, string password) { UserName = userName; Organization = organization; Email = email; // set hashed password text to PasswordHash. PasswordHash = new PasswordHasher<ApplicationUser>() .HashPassword(this, password); // Get error LastUpdateDate = DateTime.Now; } ... } } 
Enter fullscreen mode Exit fullscreen mode

Error

InvalidCastException: Cannot write DateTime with Kind=Local to PostgreSQL type 'timestamp with time zone', only UTC is supported. Note that it's not possible to mix DateTimes with different Kinds in an array/range. See the Npgsql.EnableLegacyTimestampBehavior AppContext switch to enable legacy behavior. 
Enter fullscreen mode Exit fullscreen mode

So I had to convert to Universal time.

ApplicationUser.cs

using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.AspNetCore.Identity; namespace ApprovementWorkflowSample.Applications { public class ApplicationUser: IdentityUser<int> { ... [Required] [Column("last_update_date", TypeName = "timestamp with time zone")] public DateTime LastUpdateDate { get; set; } ... public void Update(string userName, string? organization, string email, string password) { UserName = userName; Organization = organization; Email = email; // set hashed password text to PasswordHash. PasswordHash = new PasswordHasher<ApplicationUser>() .HashPassword(this, password); // OK LastUpdateDate = DateTime.Now.ToUniversalTime(); } ... } } 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)