Conguratulations on the releasing .NET Core 3.0 and ASP.NET Core 3.0!
Today's theme is about upgrading ASP.NET Core from ver.2.2 to ver.3.0.
IHostingEnvironment and UseMvc had been changed.(Thank you for teaching me alternatives:) )
I changed only one class, Startup.cs.
It separated middleware systems(for example MVC, Razor Pages, etc.) like below code.
Furthermore, it separated routing from endpoint.
UseEndpoints required routing.
So this caused an exception.
But if there ware no endpoints, no exceptions were occurred and the white page was shown;P.
Next time, I will try login/logout by ASP.NET Core Identity.
Today's theme is about upgrading ASP.NET Core from ver.2.2 to ver.3.0.
What I did
- Creating an empty ASP.NET Core project(ver.2.2.402)
- Adding EntityFrameworkCore by NuGet
- Adding some codes
- Upgrading to ver.3.0.100
- Fixing some problems
Setup
Environments
- .NET Core : ver.2.2.402, ver.3.0.100
- Microsoft.EntityFrameworkCore : ver.2.2.6, ver.3.0.0
- Npgsql.EntityFrameworkCore.PostgreSQL : ver.2.2.4, ver.3.0.1
- Windows10 : ver.1903
- Rider : ver.2019.2.3
- PostgreSQL : ver.12.0
Creating the base project
UpgradeSample.csproj
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.4" /> </ItemGroup> </Project>
Program.cs
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; namespace UpgradeSample { public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); } }
Startup.cs
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json.Serialization; using UpgradeSample.Models; using UpgradeSample.Products; namespace UpgradeSample { public class Startup { private IConfigurationRoot Configuration { get; } public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", false, true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", false, true) .AddEnvironmentVariables(); Configuration = builder.Build(); } public void ConfigureServices(IServiceCollection services) { // DB Connect services.AddDbContext<UpgradeSampleContext>(options => options.UseNpgsql(Configuration["DbConnect"])); // for setting JSON parameter names pascal case. services.AddMvc() .AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); }); // DI services.AddScoped<IProductDao, Productdao>(); services.AddScoped<IProductService, ProductService>(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseMvc(); } } }
For routing
ApiController.cs
using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using UpgradeSample.Models; using UpgradeSample.Products; namespace UpgradeSample.Controllers { public class ApiController: Controller { private readonly IProductService _productService; public ApiController(IProductService productService) { _productService = productService; } [Route("/")] [Route("/Home")] public string Index() { return "hello"; } [HttpGet] [Route("/products")] public async Task<List<Product>> GetProducts() { return await _productService.GetProductsAsync(); } } }
For DB accessing
UpgradeSampleContext.cs
using Microsoft.EntityFrameworkCore; namespace UpgradeSample.Models { public class UpgradeSampleContext: DbContext { public UpgradeSampleContext(DbContextOptions<UpgradeSampleContext> options) :base(options) { } public DbSet<Product> Products { get; set; } } }
Product.cs
using System.ComponentModel.DataAnnotations.Schema; namespace UpgradeSample.Models { [Table("Product")] public class Product { [Column("ProductId")] public int? ProductId { get; set; } [Column("ProductName")] public string ProductName { get; set; } } }
IProductService.cs
using System.Collections.Generic; using System.Threading.Tasks; using UpgradeSample.Models; namespace UpgradeSample.Products { public interface IProductService { Task<List<Product>> GetProductsAsync(); } }
ProductService.cs
using System.Collections.Generic; using System.Threading.Tasks; using UpgradeSample.Models; namespace UpgradeSample.Products { public class ProductService: IProductService { private readonly IProductDao _productDao; public ProductService(IProductDao productDao) { _productDao = productDao; } public async Task<List<Product>> GetProductsAsync() { return await _productDao.GetProductsAsync(); } } }
IProductDao.cs
using System.Collections.Generic; using System.Threading.Tasks; using UpgradeSample.Models; namespace UpgradeSample.Products { public interface IProductDao { Task<List<Product>> GetProductsAsync(); } }
ProductDao.cs
using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using UpgradeSample.Models; namespace UpgradeSample.Products { public class ProductDao: IProductDao { private readonly UpgradeSampleContext _context; public ProductDao(UpgradeSampleContext context) { _context = context; } public async Task<List<Product>> GetProductsAsync() { return await _context.Products.ToListAsync(); } } }
DB
SQL
CREATE TABLE "Product"(
"ProductId" serial PRIMARY KEY,
"ProductName" text NOT NULL
);
INSERT INTO "Product"(
"ProductName"
)
VALUES
(
'Nykee Running Shoes'
);
INSERT INTO "Product"(
"ProductName"
)
VALUES
(
'South Face Jacket'
);
Upgrade to ver.3.0.100
I changed 2 files and restored.global.json
{ "sdk": { "version": "3.0.100" } }
UpgradeSample.csproj
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.0.1" /> </ItemGroup> </Project>
Fix problems
After upgrading, I found 3 warnings.Startup.cs(15, 24): [CS0618] 'IHostingEnvironment'is obsolete ('This type is obsolete and will be removed in a future version. The recommended alternative is Microsoft.AspNetCore.Hosting.IWebHostEnvironment.') Startup.cs(35, 56): [CS0618] 'IHostingEnvironment'is obsolete ('This type is obsolete and will be removed in a future version. The recommended alternative is Microsoft.AspNetCore.Hosting.IWebHostEnvironment.') Startup.cs(42, 13): [MVC1005] Using 'UseMvc' to configure MVC is not supported while using Endpoint Routing. To continue using 'UseMvc', please set 'MvcOptions.EnableEndpointRouting = false' inside 'ConfigureServices'.
IHostingEnvironment and UseMvc had been changed.(Thank you for teaching me alternatives:) )
I changed only one class, Startup.cs.
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using UpgradeSample.Models;
using UpgradeSample.Products;
namespace UpgradeSample
{
public class Startup
{
private IConfigurationRoot Configuration { get; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", false, true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
// DB Connect
services.AddDbContext<UpgradeSampleContext>(options =>
options.UseNpgsql(Configuration["DbConnect"]));
// for setting JSON parameter names pascal case.
services.AddControllers()
.AddJsonOptions(options =>
options.JsonSerializerOptions.PropertyNamingPolicy = null);
// DI
services.AddScoped<IProductDao, Productdao>();
services.AddScoped<IProductService, ProductService>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// for attribute-routing.
endpoints.MapControllers();
});
}
}
}
Endpoint Routing
I thought the main reason of this change was caused by using Endpoint Routing.It separated middleware systems(for example MVC, Razor Pages, etc.) like below code.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddRazorPages();
}
Furthermore, it separated routing from endpoint.
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
UseEndpoints required routing.
So this caused an exception.
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Exception was occurred at the runtime.
// app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
But if there ware no endpoints, no exceptions were occurred and the white page was shown;P.
Next time, I will try login/logout by ASP.NET Core Identity.
Resources
- Migrate from ASP.NET Core 2.2 to 3.0 - Microsoft Docs
- What's new in ASP.NET Core 3.0 - Microsoft Docs
- Comparing Startup.cs between the ASP.NET Core 3.0 templates: Exploring ASP.NET Core 3.0 - Part 2 - Andrew Lock | .NET Escapades
- My First Look at ASP.NET Core 3.0 - Shawn Wildermuth
- Routing in ASP.NET Core - Microsoft Docs
- Format response data in ASP.NET Core Web API - Microsoft Docs
- Understanding ASP.NET Core Endpoint Routing - aregcode
- Endpoint Routing in ASP.NET Core 3.0 - Shawn Wildermuth
- ASP.NET Core / Entity Framework Core 3.0 の気になった機能と 2.2 からの移行 - しばやん雑記
- ASP.NET Core 2.2 で追加された Endpoint Routing と Core MVC での互換性 - しばやん雑記
コメント
コメントを投稿