zoukankan      html  css  js  c++  java
  • ASP.NET Core 2.0升级到3.0的变化和问题

    前言

    在.NET Core 2.0发布的时候,博主也趁热使用ASP.NET Core 2.0写了一个独立的博客网站,现如今恰逢.NET Core 3.0发布之际,于是将该网站进行了升级。

    下面就记录升级过程中遇到的一些变化和问题。同时也小广告一波,欢迎大家多来我的博客逛逛:不落阁 - 一个.NET程序员的个人博客

    正文

    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 });

    QQ登录问题

    升级到ASP.NET Core 3.0后,之前使用的Microsoft.AspNetCore.Authentication.QQ包已经不能正常使用了,经过源码调试后,我发现是因为对OAuthHandler里面的ExchangeCodeAsync等方法的重写未生效,导致QQ返回的数据(QQ返回的数据比较特殊)转化为Json的时候出错。Nuget上Microsoft.AspNetCore.Authentication.OAuth依旧是2.2.4版本,而Microsoft.AspNetCore.Authentication.MicrosoftAccount、Microsoft.AspNetCore.Authentication.Google等包都已经升级为3.0.0,看了公告https://github.com/aspnet/AspNetCore/issues/10991确实已经改了,只是我们能获取到的依旧是2.2.4版。

    最后在Github上发现了一个第三方认证的集合项目:https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers,在上面找到了QQ登录的包AspNet.Security.OAuth.QQ

    可以看到Nuget上的依旧是2.1.0,这个显然也不能用,不过myget上已经有3.0.0预览版的了。

    按照PM指令安装的话会提示找不到这个包对应的版本,最新版是2.1.0,所以这里要手动下载nupkg文件

    用法和之前差不多,只是有两处细微改动:

    1.AppId和AppKey改成了统一的ClientId和ClientSercert

    2.openid不能映射成自定义Claim名称,所以后面处理的时候只能通过系统定义的ClaimTypes.NameIdentifier来获取。

    注意:这段图片设置了防盗链,懒得重新上传,请到作者博客查看详情:https://www.leo96.com/article/detail/47

    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是一样的

    更多问题待定,先介绍到这来。

    感谢翻阅,敬请斧正!

    本文最初发表于:https://www.leo96.com/article/detail/47

  • 相关阅读:
    Openstack API 开发 快速入门
    virtualBox虚拟机到vmware虚拟机转换
    使用Blogilo 发布博客到cnblogs
    Openstack Troubleshooting
    hdoj 1051 Wooden Sticks(上升子序列个数问题)
    sdut 2430 pillars (dp)
    hdoj 1058 Humble Numbers(dp)
    uva 10815 Andy's First Dictionary(快排、字符串)
    sdut 2317 Homogeneous squares
    hdoj 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列+二分)
  • 原文地址:https://www.cnblogs.com/LY2016start/p/11661786.html
Copyright © 2011-2022 走看看