• ASP.NET Core 2.0升级到3.0的变化和问题【转】


    Host变化

    Program.cs中WebHostBuilder变为HostBuilder,ASP.NET Core 3.0使用通用主机,而主机配置方式也有所改变,主要集中通过ConfigureWebHostDefaults方法。

    以下是升级前后的代码:

     1 //升级前:ASP.NET Core 2.0
     2 WebHost.CreateDefaultBuilder(args)
     3     .UseUrls("http://127.0.0.1:5002")
     4     .UseStartup<Startup>()
     5     .ConfigureLogging(logging =>
     6     {
     7         logging.ClearProviders();
     8         logging.SetMinimumLevel(LogLevel.Trace);
     9     })
    10     .UseNLog();
    11 //升级后:ASP.NET Core 3.0
    12 Host.CreateDefaultBuilder(args)
    13     .ConfigureWebHostDefaults(webBuilder =>
    14     {
    15         webBuilder.UseStartup<Startup>()
    16         .UseUrls("http://127.0.0.1:5002")
    17         .ConfigureLogging(logging =>
    18         {
    19             logging.ClearProviders();
    20             logging.SetMinimumLevel(LogLevel.Trace);
    21         })
    22         .UseNLog();
    23     });

    Startup.cs变化

    配置服务方面:AddControllersWithViews替代了原来的AddMVC。

    配置管道方面:UseMVC、UseSignalR统一替换为UseEndpoints,此外增加了UseRouting,UseAuthentication、UseAuthorization必须位于UseRouting和useEndpoints之间。

     1 //升级前
     2 app.UseAuthentication();
     3 app.UseSignalR(routes =>
     4 {
     5     routes.MapHub<ChatRoom>("/chatroom");
     6 });
     7 app.UseMvc(routes =>
     8 {
     9     routes.MapRoute(
    10         name: "default",
    11         template: "{controller=Home}/{action=Index}/{id?}");
    12 });
    13 //升级后
    14 app.UseRouting();
    15 app.UseAuthentication();
    16 app.UseAuthorization();
    17 app.UseEndpoints(endpoints =>
    18 {
    19     endpoints.MapControllerRoute(
    20         name: "default",
    21         pattern: "{controller=Home}/{action=Index}/{id?}");
    22     endpoints.MapHub<ChatRoom>("/chatroom");
    23 });

    Json序列化问题

    .NET Core 3.0引入了新的JSON API,并且ASP.NET Core已经移除了Newtonsoft.Json的引用,默认使用System.Text.Json来序列化Json,而新的JSON API主打性能,所以没有JSON.NET全面。

    由于使用了Entity Framework,所以在直接序列化实体类时,导航属性会出现循环引用的问题,而System.Text.Json并没有提供解决循环引用问题的相关配置。

    在Github上找了下,似乎官方也提到这个问题,但在3.0版本并未提供解决办法:https://github.com/dotnet/corefx/issues/38579

    因此不得不使用原来的JSON API,也就是JSON.NET(Newtonsoft.Json)

    要在ASP.NET Core 3.0中使用Newtonsoft.Json,需要安装Microsoft.AspNetCore.Mvc.NewtonsoftJson包,并在Startup中配置。如下所示:

     1 //升级前
     2 services.AddMvc()
     3     .AddJsonOptions(options =>
     4     {
     5         options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //序列化时key为驼峰样式
     6         options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
     7         options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
     8         options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;    //忽略循环引用
     9     });
    10 //升级后(需要引入Microsoft.AspNetCore.Mvc.NewtonsoftJson包)
    11 services.AddControllersWithViews()
    12     .AddNewtonsoftJson(options =>
    13     {
    14         options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //序列化时key为驼峰样式
    15         options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
    16         options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
    17         options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;    //忽略循环引用
    18     });

    EFCore客户端求值

    EF Core 3.0不再支持客户端求值,需要Linq查询出来后再手动运算。

     1 //升级前
     2 detailModel.SimilarArticles = await _dbContext.Article
     3     .Where(s => s.Status == (int)CommonStatus.Valid && StringSimilarity.Calculate(article.Title, s.Title) > 0.3m && s.Id != article.Id)
     4     .Select(s => new Article()
     5     {
     6         Id = s.Id,
     7         CreateTime = s.CreateTime,
     8         Title = s.Title
     9     })
    10     .OrderBy(s => Guid.NewGuid())
    11     .Take(8)
    12     .ToListAsync();
    13 //升级后
    14 var similarArticles = await _dbContext.Article
    15     .Where(s => s.Status == (int)CommonStatus.Valid && s.Id != article.Id)
    16     .Select(s => new Article()
    17     {
    18         Id = s.Id,
    19         CreateTime = s.CreateTime,
    20         Title = s.Title
    21     })
    22     .ToListAsync();
    23 similarArticles = similarArticles.Where(s => StringSimilarity.Calculate(article.Title, s.Title) > 0.3m).OrderBy(s => Guid.NewGuid()).Take(8).ToList();

    以上代码片段是筛选与某文章标题相似的文章,其中StringSimilarity.Calculate(string,string)方法是客户端上计算两个标题相似度的算法,3.0后EF Core已经不支持直接写到Linq查询中,会报异常,大概意思是无法翻译Linq语句。

    实际上升级前后两种写法生成的SQL是一样的。

  • 相关阅读:
    servlet中如何实现通过Spring实现对象的注入
    异步Socket
    JAVA NIO实现
    【Java并发】
    JAVA实现阻塞队列
    lock与synchronized比较
    线程执行顺序
    ConcurrentHashMap 1.8
    LeetCode 416 分割等和子集
    linux常用指令
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/12341402.html
Copyright © 2020-2023  润新知