Search code examples
asp.net-core.net-6.0

Exception unhandled when I upgrade .NET Core 3.1 to .NET 6


I upgraded a project from .NET Core 3.1 to .NET 6 (Web API). Then I fixed errors and applied new syntax as documented by Microsoft. Also, when I start the project in debug mode, it shows this exception in Program.cs:

CreateHostBuilder(args).Build().Run();

System.InvalidOperationException: 'Can't compile a NewExpression with a constructor declared on an abstract class'

My code at Program.cs:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Linq;
using Serilog;
using Serilog.Events;
using Microsoft.Extensions.Hosting;

namespace Portal.Api
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Serilog config
            Log.Logger = new LoggerConfiguration()
           .MinimumLevel.Debug()
           .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
           .Enrich.FromLogContext()
           .CreateLogger();

            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseServiceProviderFactory(new AutofacServiceProviderFactory())
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddEnvironmentVariables();
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
                    config.AddJsonFile("appsettings.config.json", optional: true, reloadOnChange: true);
#if DEBUG
                    config.AddJsonFile("appsettings.Development.json", optional: false, reloadOnChange: true);
                    var subConfig = Directory.GetFiles(Directory.GetCurrentDirectory(), "appsettings.Dev-*.json", SearchOption.TopDirectoryOnly)
                        .Where(e => !e.EndsWith("appsettings.Development.json"))
                        .ToList();

                    if (subConfig.Count > 0)
                    {
                        foreach (var file in from string path in subConfig let file = Path.GetFileName(path) select file)
                            config.AddJsonFile(file, true, true);
                    }
#endif
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

and Startup.cs


using AspNetCoreRateLimit;
using Autofac;
using Autofac.Core;
using Autofac.Extensions.DependencyInjection;
using AutoMapper;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Portal.Api.Common;
using Portal.Api.CoreProcess;
using Portal.Api.EvaluateProcess;
using Portal.Api.EventProcess;
using Portal.Api.Middleware;
using Portal.Api.Plugins;
using Portal.Api.Plugins.SlackLogger;
using Portal.Api.Provider;
using Portal.Common;
using Portal.Data;
using Portal.Repository;
using Portal.Services;
using Portal.Services.Impl;
using Portal.Services.Interface;
using ServiceStack;
using ServiceStack.Text;
using System;
using System.Globalization;
using System.IO;
using System.Text;

namespace Portal.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            //var configuration = new ConfigurationBuilder()
            //    .SetBasePath(Directory.GetCurrentDirectory())
            //    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            //    //.AddJsonFile(@"App_Data\message.json", optional: false, reloadOnChange: false)// custom config file
            //    .Build();
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; private set; }

        public ILifetimeScope AutofacContainer { get; private set; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDistributedMemoryCache();

            services.AddSession(options =>
            {
                options.Cookie.HttpOnly = false;
                options.Cookie.IsEssential = true;
            });

            services.AddControllers()
                    .AddNewtonsoftJson(options =>
                    {
                        options.UseMemberCasing();
                    });

            services.AddCors();
            services.AddMemoryCache();
            services.RegisterPlugins();
            services.AddControllers().AddNewtonsoftJson();
            var defaultConnection = Configuration["DefaultConnection"];
            var encyptor = Configuration.GetValue($"Encyptor:{defaultConnection}", string.Empty);
            string conStr = Configuration.GetConnectionString(Configuration["DefaultConnection"]);
            if (!string.IsNullOrEmpty(encyptor))
            {
                var enable = Configuration.GetValue("Encyptor:Enable", true);
                if (enable)
                {
                    try
                    {
                        Uri uri = new Uri(new Uri(encyptor), "GetConnection");
                        var base64EncodedData = uri.OriginalString.GetStringFromUrl();
                        if (!string.IsNullOrEmpty(base64EncodedData))
                        {
                            var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
                            conStr = Encoding.UTF8.GetString(base64EncodedBytes);
                        }
                    }
                    catch (Exception)
                    {
                        var error = new Exception("Can not connect to Encryptor");
                        throw error;
                    }
                }
            }
            services.AddDbContext<PortalDbContext>(item => item.UseSqlServer(conStr));
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "Development",
                    Title = "ezHR Portal Public API",
                    Description = "ASP.NET Core Web API"
                });
                c.CustomSchemaIds(type => type.ToString());
            });
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            var SecretKey = Encoding.ASCII.GetBytes(GlobalParam.SECRET_KEY);
            var ezAuthSection = Configuration.GetSection("Auth").Get<Data.Dtos.AuthSection>() ?? new Data.Dtos.AuthSection();

            services.AddSingleton(ezAuthSection);

            // Configure JWT Token Authentication
            if (ezAuthSection.Enable && ezAuthSection.Okta)
            {
                services.AddAuthentication(sharedOptions =>
                {
                    sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                    Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
                })
               .AddJwtBearer(options =>
               {
                   options.TokenValidationParameters = new TokenValidationParameters
                   {
                       ValidateIssuer = true,
                       ValidIssuer = ezAuthSection.Url,
                       ValidateAudience = true,
                       ValidAudience = ezAuthSection.Url,
                       ValidateIssuerSigningKey = false,
                       SignatureValidator = delegate (string token, TokenValidationParameters parameters)
                       {
                           var jwt = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(token);
                           return jwt;
                       },
                       RequireExpirationTime = false,
                       ValidateLifetime = true,
                       NameClaimType = GlobalParam.NameIdentifierClaimType
                   };
               });
            }
            else if (ezAuthSection.Enable && !string.IsNullOrEmpty(ezAuthSection.NameClaimType))
            {
                var nameClaim = ezAuthSection.NameClaimType;
                services.AddAuthentication(sharedOptions =>
                {
                    sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                    Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
                })
               .AddJwtBearer(options =>
               {
                   options.TokenValidationParameters = new TokenValidationParameters
                   {
                       ValidateIssuer = false,
                       ValidIssuer = ezAuthSection.Url,
                       ValidateAudience = false,
                       ValidAudience = ezAuthSection.Url,
                       ValidateIssuerSigningKey = false,
                       SignatureValidator = delegate (string token, TokenValidationParameters parameters)
                       {
                           var jwt = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(token);
                           return jwt;
                       },
                       RequireExpirationTime = false,
                       ValidateLifetime = true,
                       NameClaimType = nameClaim
                   };
               });
            }
            else
            {
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        options.Authority = ezAuthSection.Url;
                        options.RequireHttpsMetadata = false;
                        options.Audience = $"{ezAuthSection.Url}/resources";

                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            NameClaimType = GlobalParam.NameIdentifierClaimType
                        };
                    })
                    .AddJwtBearer("ezHR9", token =>
                    {
                        token.RequireHttpsMetadata = false;
                        token.SaveToken = true;
                        token.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuerSigningKey = true,
                            IssuerSigningKey = new SymmetricSecurityKey(SecretKey),
                            ValidateIssuer = false,
                            ValidateAudience = false,
                            RequireExpirationTime = true,
                            ValidateLifetime = true,
                            ClockSkew = TimeSpan.Zero
                        };
                    });

                services.AddAuthorization(options =>
                {
                    var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme, "ezHR9");
                    defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();

                    options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
                });
            }

            ConfigJson();

            // Repository DI
            services.AddScoped<IRepositoryFactory, UnitOfWork<PortalDbContext>>();
            services.AddScoped<IUnitOfWork, UnitOfWork<PortalDbContext>>();
            services.AddScoped<IUnitOfWork<PortalDbContext>, UnitOfWork<PortalDbContext>>();
            services.AddScoped<IUserSession, UserSession>();
            services.AddScoped<ITR_FinalTeacherWorkingService, TR_FinalTeacherWorkingService>();
            services.AddScoped<IHR_BankService, HR_BankService>();
            services.AddScoped<IHR_EmployeeAccountService, HR_EmployeeAccountService>();
            services.AddSingleton<IUserSessionFactory>(provider => new UserSessionFactory(provider));
            services.AddSingleton<Plugins.Locales.ILocales, Plugins.Locales.Locales>();

            // Custom DI
            services.RegisterProvider();
            // Add services to the collection
            services.AddOptions();

            // Rate limit DI
            services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
            services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
            services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
            services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
            services.AddHttpContextAccessor();
            services.AddAutoMapper(typeof(Startup));

            //// Create a container-builder and register dependencies
            //var builder = new ContainerBuilder();

            //// Populate the service-descriptors added to `IServiceCollection`
            //builder.Populate(services);

            //// Register dependency directly with Autofac
            //builder.RegisterWebRepository();
            //builder.RegisterWebServices();
            //builder.RegisterEventProcessDI();
            //builder.RegisterEvaluateProcessDI();
            //builder.RegisterCoreProcessDI();
            //builder.RegisterType<MongoDBHelper>();
            //AutofacContainer = builder.Build();

            //// this will be used as the service-provider for the application!
            //return new AutofacServiceProvider(AutofacContainer);
        }

        public void ConfigureContainer(ContainerBuilder builder)
        {
            // Register your own things directly with Autofac
            // Populate the service-descriptors added to `IServiceCollection`
            //builder.Populate(services);

            // Register dependency directly with Autofac
            builder.RegisterWebRepository();
            builder.RegisterWebServices();
            builder.RegisterEventProcessDI();
            builder.RegisterEvaluateProcessDI();
            builder.RegisterCoreProcessDI();
            builder.RegisterType<MongoDBHelper>();
            //AutofacContainer = builder.Build();

            // this will be used as the service-provider for the application!
            // return new AutofacServiceProvider(AutofacContainer);
            //...
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.EnvironmentName == Environments.Development)
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            var aspNetCoreTemp = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ASPNETCORE_TEMP");
            if (!Directory.Exists(aspNetCoreTemp))
            {
                Directory.CreateDirectory(aspNetCoreTemp);
            }

            Environment.SetEnvironmentVariable("ASPNETCORE_TEMP", aspNetCoreTemp ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "StaticFiles"));
            var slackConfiguration = Configuration.GetSection("SlackConfiguration").Get<SlackConfiguration>();
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseCors(builder => builder
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .SetIsOriginAllowed(org => true)
                //.AllowCredentials()
                );

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseSession();


            app.UseIpRateLimiting();
            // use 2 custom middleware before UseMVC to handle request
            app.UseMiddleware(typeof(CaptureRequestMiddleware));
            app.UseMiddleware(typeof(ErrorHandlingMiddleware));

            app.UseSwagger();
            app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "ezHR Portal Public API"); });
            //app.UseMvc();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(
                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "StaticFiles")),
                RequestPath = "/StaticFiles"
            });

            app.EnrichLog();

            if (env.IsDevelopment())
            {
                app.UseFileServer(new FileServerOptions()
                {
                    FileProvider = new PhysicalFileProvider(
                    Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "StaticFiles")),
                    RequestPath = new PathString("/StaticFiles"),
                    EnableDirectoryBrowsing = true
                });
            }

            // giả lập call 1 service để giảm thời gian request lần đầu ở client
            Console.WriteLine("Starting application...");
            MockResolve(app);
        }

        private void MockResolve(IApplicationBuilder app)
        {
            var serviceProvider = app.ApplicationServices;
            _ = serviceProvider.GetService<EventProcess.EventHandler.Register.RegisterLeaveHandler>();
        }

        private void ConfigJson()
        {
            //JsConfig.TextCase = TextCase.PascalCase;
            JsConfig.MaxDepth = 6;
            JsConfig<DateTime>.SerializeFn = date => date.ToString("o", CultureInfo.InvariantCulture);
            JsConfig<DateTime?>.SerializeFn = date => date.HasValue ? date.Value.ToString("o", CultureInfo.InvariantCulture) : string.Empty;
            JsConfig<TimeSpan>.SerializeFn = time => (time.Ticks < 0 ? "-" : "") + time.ToString("hh':'mm':'ss'.'fffffff");
            JsConfig<TimeSpan?>.SerializeFn = time => time.HasValue ? (time.Value.Ticks < 0 ? "-" : "") + time.Value.ToString("hh':'mm':'ss'.'fffffff") : null;
            JsConfig<Guid>.SerializeFn = guid => guid.ToString("D");
            JsConfig<Guid?>.SerializeFn = guid => null;
        }
    }
}

I searched and lookup many case about upgrade .NET Core 3.1 to .NET 6 but I think this case is exception


Solution

  • The three steps to be followed for Non-Blazor .NET core 3.1 to 6.0.

    Step1: Upgrade the Target Framework. Right-click on the project file and open the property in which the target framework can be changed.

    enter image description here

    Step2: Update the package References: Edit the project file in Notepad++ or in solution explorer in VSS. Upgrade the ASP.NET core 3.1 associated packages to 6.0

    <ItemGroup>
      <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.6" />
      <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.6" />
      <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="3.1.6" />
      <PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
    

    To

      <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.0" />
      <PackageReference Include=" Microsoft.EntityFrameworkCore.Tools" Version="6.0.0" />
      <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
      <PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
    </ItemGroup>
    

    Step3: Bin and Obj folder: Bin and Obj folder can be deleted manually or apply the below line.

    dotnet nuget locals --clear all
    

    Step 4: Rebuild/ compile the project.

    Step 5: Docker Image: If application uses the docker, the below command can be used for it

    docker pull mcr.microsoft.com/dotnet/aspnet:6.0