前言

在.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方法。

以下是升级前后的代码:

 //升级前:ASP.NET Core 2.0
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://127.0.0.1:5002")
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog();
//升级后:ASP.NET Core 3.0
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.UseUrls("http://127.0.0.1:5002")
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog();
});

Startup.cs变化

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

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

 //升级前
app.UseAuthentication();
app.UseSignalR(routes =>
{
routes.MapHub<ChatRoom>("/chatroom");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
//升级后
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapHub<ChatRoom>("/chatroom");
});

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中配置。如下所示:

 //升级前
services.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //序列化时key为驼峰样式
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //忽略循环引用
});
//升级后(需要引入Microsoft.AspNetCore.Mvc.NewtonsoftJson包)
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //序列化时key为驼峰样式
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //忽略循环引用
});

EFCore客户端求值

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

 //升级前
detailModel.SimilarArticles = await _dbContext.Article
.Where(s => s.Status == (int)CommonStatus.Valid && StringSimilarity.Calculate(article.Title, s.Title) > 0.3m && s.Id != article.Id)
.Select(s => new Article()
{
Id = s.Id,
CreateTime = s.CreateTime,
Title = s.Title
})
.OrderBy(s => Guid.NewGuid())
.Take()
.ToListAsync();
//升级后
var similarArticles = await _dbContext.Article
.Where(s => s.Status == (int)CommonStatus.Valid && s.Id != article.Id)
.Select(s => new Article()
{
Id = s.Id,
CreateTime = s.CreateTime,
Title = s.Title
})
.ToListAsync();
similarArticles = similarArticles.Where(s => StringSimilarity.Calculate(article.Title, s.Title) > 0.3m).OrderBy(s => Guid.NewGuid()).Take().ToList();

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

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

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

感谢翻阅,敬请斧正!

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

ASP.NET Core 2.0升级到3.0的变化和问题的更多相关文章

  1. 将 ASP.NET Core 2.1 升级到最新的长期支持版本ASP.NET Core 3.1

    目录 前言 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 消失了 升级到 ASP.NET Core 3.1 项目文件(.csproj) Program. ...

  2. IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API

    IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习之保护API. 使用IdentityServer4 来实现使用客户端凭据保护ASP.N ...

  3. asp.net core 从 3.1 到 5.0

    asp.net core 从 3.1 到 5.0 Intro 就在前几天,微软宣布了 .NET5 发布了 RC1 版本,这也意味着 .NET5 的开发基本稳定了,正式发布之前,不会再新增新的 Feat ...

  4. 系统补丁更新导致MVC3.0.0升级到3.0.1的问题解决

    在更新了系统补丁之后,会不知觉的将MVC3.0.0升级到MVC3.0.1的问题,解决的思路如下: 1.全部MVC引用使用NuGet进行包的管理. 2.单独把MVC库抽离出来,然后放在单独的项目文件夹, ...

  5. 从OLLVM4.0.0升级到LLVM8.0.1,并且给LLVM增加Pass 插件系统

    版本太低了,用得我这个揪心. 上周日决定把手头的ollvm从4.0.0升级到LLVM8.0.1. 里面的Pass的话,决定移植到8.0.1里面. 我习惯从代码上来动手 1:下载LLVM  https: ...

  6. 从 ASP.NET Core 3.1 迁移到 5.0

    3月中旬,微软官方已经发布了dotnet 5的第一个预览版:5.0.0-preview.1. dotnet core经过前几个版本的发展和沉淀,到3.1已经基本趋于稳定. 所以从.net core 3 ...

  7. asp.net core 1.1 升级后,操作mysql出错的解决办法。

    遇到问题 core的版本从1.0升级到1.1,操作mysql数据库,查询数据时遇到MissingMethodException问题,更新.插入操作没有问题. 如果你也遇到这个问题,请参照以下步骤进行升 ...

  8. ASP.NET Core 2.2 迁移至 3.0 备忘录

    将 ASP.NET Core 2.2 迁移至 ASP.NET Core 3.0 需要注意的地方记录在这篇随笔中. TargetFramework 改为 netcoreapp3.0 <Target ...

  9. asp.net core 支付宝支付( 电脑2.0)

    支付宝电脑支付实测在手机浏览器也可以唤醒手机支付宝进行支付,因此也可以作为支付宝手机web支付方式.支付宝电脑支付流程为使用支付宝官方sdk通过获取的支付宝参数构造DefaultAopClient实例 ...

随机推荐

  1. MySQL的select详细介绍

    MySQL 查询数据 MySQL 数据库使用SQL SELECT语句来查询数据. 你可以通过 mysql> 命令提示窗口中在数据库中查询数据 语法 以下为在MySQL数据库中查询数据通用的 SE ...

  2. Nginx+lamp构建动静分离项目

    一.nginx代理的概述 概述:nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个内部网络代理上网的代理 ...

  3. 数据结构篇——平衡二叉树(AVL树)

    引入 上一篇写了二叉排序树,构建一个二叉排序树,如果构建序列是完全有序的,则会出现这样的情况: 显然这种情况会使得二叉搜索树退化成链表.当出现这样的情况,二叉排序树的查找也就退化成了线性查找,所以我们 ...

  4. Java多线程编程核心技术-第6章-单例模式与多线程-读书笔记

    第 6 章 单例模式与多线程 本章主要内容 如何使单例模式遇到多线程是安全的.正确的. 6.1 立即加载 / “饿汉模式” 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就 ...

  5. C#中的函数(三)参数传递及返回值

    接前面二篇,继续开始新的研究 前面忘了说什么是主调函数与被调函数 主调函数:执行调用其它函数语句所在的函数 被调函数:被其它函数所调用的函数 简单说就是一个是发起调用者,另一个是被调用者 写个小例子说 ...

  6. 清理Linux 磁盘空间

    1.执行   lsof | grep deleted发现有大量刚刚删除文件的进程存在,kill掉进程(或者重启进程)   OK 2.查看磁盘信息:df -lh 3.循环定位最大文件目录:du -h - ...

  7. mysql之字段的修改,添加、删除,多表关系(外键),单表详细操作(增删改)

    字段的修改.添加和删除 create table tf1( id int primary key auto_increment, x int, y int ); #修改 alter table tf1 ...

  8. Box HDU - 2475 (Splay 维护森林)

    Box \[ Time Limit: 5000 ms \quad Memory Limit: 32768 kB \] 题意 给出 \(n\) 个箱子的包含关系,每次两种操作. 操作 \(1\):把 \ ...

  9. Pandas | 15 窗口函数

    为了处理数字数据,Pandas提供了几个变体,如滚动,展开和指数移动窗口统计的权重. 其中包括总和,均值,中位数,方差,协方差,相关性等.本章讨论的是在DataFrame对象上应用这些方法. .rol ...

  10. 使用plv8+hashids生成短链接服务

    有写过一个集成npm plv8 以及shortid生成短链接id服务,实际上我们可以集成触发器自动生成url对应的短链接地址,hashids也是一个不错的选择. 以下是一个别人写的一个博客实现可以参考 ...