.net core迁移实践:项目文件csproj的转换
随着net core的不断更新和生产可用,越来越多的人把现有的应用迁移和部署到net core平台。本文将分享迁移过程中的一个环节,给大家做一下参考。
背景说明
先来介绍一下什么是SDK样式的文件结构。关注net core发展的同学应该对早期的项目定义文件project.json还有点印象。.net开发组在net core 1.0版本时是准备抛弃xml格式的csproj文件而改为json格式的project.json来定义和描述项目的。但是后来主要由于MSBuild的兼容问题,不得不放弃project.json转移回xml格式的csproj(详见https://devblogs.microsoft.com/dotnet/announcing-net-core-tools-msbuild-alpha/)。
然而由于传统.net framework的csproj文件内容繁杂,可读性和操作性较差,因此微软重新定义了新样式的csproj文件内容样式。其最大化的保持了和原有xml属性的兼容,并添加了一些新的特性。由于新格式的csproj文件总是以:
<Project Sdk="Microsoft.NET.Sdk"></Project>
标记来定义,所以称之为SDK样式。
一个典型的.net framework平台的csproj文件结构如下图所示:

其中包含了项目的编译配置、调试生成配置、大量的nuget文件依赖、大量的cs源代码文件路径等,造成了此文件内容的非常繁多,阅读和分析都有比较大的困难。
而SDK样式的csproj文件内容就非常精简了,如下图所示:

其中TargetFrameworks配置项目的多目标平台,可选的值有netstandard2.1;net451;netcoreapp3.1,三种格式分别代表net standard、net framework、net core目标平台。此处的配置根据各人的项目定位不同设置所需的值。我们公司的业务程序是跑在特定的运行容器下的,迁移过程也是分阶段展开,最终我们采取先同时编译两个目标平台dll的方案。
由以上对比可见,SDK样式的csproj内容精简的一大原因就是文件的依赖(cs源码和nuget包文件)不需要在csproj中明确写明。针对cs源码及目录结构,VS自动识别项目目录内的文件结构作为项目结构,这一点改变真是点赞。因为文件及目录不需要csproj这个中间层再多一次描述,相当于“所见即所得”,相信大家在平时肯定遇到磁盘的源文件存在而VS项目就是看不到等类似问题,以后不会再有困惑啦。
另外针对nuget包依赖的文件也是如此,csproj不再维护nuget包内的文件明细,而改为PackageReference以nuget包为单位来管理依赖。这个改变对我们的转换几乎没有影响,重新添加一次nuget引用即可;同时再说一句:net core是不支持packages.config文件管理nguet包,建议大家提前就将nuget包的管理改为PackageReference方式;
csproj文件转换的操作步骤
有了以上的背景说明,接下来的工作就是针对要迁移的项目csproj文件执行改造,其实微软也提供了一些辅助工具(dotnet try-convert等)来帮助迁移,但是必须先保证迁移操作明确和无误后,才能逐步使用特定的辅助工具来提高效率。具体操作如下:
1. 直接备份原csproj文件然后将其清空
2. 然后粘贴如下最小化的xml代码:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.1;net451</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>
3. 调整的依赖nuget包和直接引用的程序集dll
这一步对nuget包有要求,需要其提供netstandard平台的版本,如下图:

如果是公司内部的nuget包就需要提前做好支持,而如果是依赖的第三方nguet包那就需要确认是否有net core支持了。不过当前net core已成趋势,绝大多数流行的nuget包都能够支持了。
4. 检查和处理源代码中不兼容的部分
由于从.net framework迁移到.net core确实存在部分代码不兼容的地方,因此需要一一识别并寻找替代方案。微软官方提供了不兼容说明,大家可以参考本文末尾的链接【从 .NET Framework 迁移到 .NET Core 的中断性变更】。
这里提供几种常见的不兼容情况:
- CallContext不兼容:可以通过Asynclocal替换解决。
- 原System.ComponentModel.DataAnnotations不兼容:需要单独安装nuget包System.ComponentModel.Annotations即可解决。
- System.Runtime.Remoting不兼容:暂无替换方案
5. 删除:Properties文件夹的AssemblyInfo.cs
6. 删除:packages.config文件。
7. 提醒:调整CI配置
输出目录Debug/Release目录内也分别生成了netstandard2.1和net451的2套程序集。因此假如应用了CI的话,相关设置也需要更新。
完成以上操作后,项目的结构就变成了下图的样子,这样编译通过后会生成针对特定目标平台的程序集。

总结
本文首先介绍了SDK样式的csproj文件的背景,并详细介绍了从传统.net framework项目转换到net core项目的关键步骤。根据各企业的项目规模和应用场景的不同,还需要制订合理的迁移计划,配合严格的测试工作,这样才能保证迁移工作的稳定推进,尤其要避免的是因迁移net core而带来服务异常甚至是生产事故。
祝大家迁移顺利!
参考资料
- .NET Core迁移前的准备工作
- 从 .NET Framework 迁移到 .NET Core 的中断性变更
- 从 packages.config 迁移到 PackageReference
- 从 .NET Framework 移植到 .NET Core 的概述
- .NET可移植性分- 析器
- .NET API 分析器
.net core迁移实践:项目文件csproj的转换的更多相关文章
- EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)
前言 终于踏出第一步探索EF Core原理和本质,过程虽然比较漫长且枯燥乏味还得反复论证,其中滋味自知,EF Core的强大想必不用我再过多废话,有时候我们是否思考过背后到底做了些什么,到底怎么实现的 ...
- Cookies 初识 Dotnetspider EF 6.x、EF Core实现dynamic动态查询和EF Core注入多个上下文实例池你知道有什么问题? EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)
Cookies 1.创建HttpCookies Cookie=new HttpCookies("CookieName");2.添加内容Cookie.Values.Add(&qu ...
- .Net Core迁移到MSBuild平台(二)
一.前言 在上一篇文章.Net Core迁移到MSBuild的多平台编译问题中,简单的讲了下新的项目配置文件中的节点配置,这篇我将用一些例子来详细讲下从project.json迁移到msbuild过程 ...
- Net Core迁移到MSBuild
Net Core迁移到MSBuild平台(二) 阅读目录 一.前言 二.XML定义 三.结语 回到目录 一.前言 在上一篇文章.Net Core迁移到MSBuild的多平台编译问题中,简单的讲了下 ...
- 利用Kettle进行SQLServer与Oracle之间的数据迁移实践
Kettle简介 Kettle(网地址为http://kettle.pentaho.org/)是一款国外开源的ETL工具,纯java编写,可以在Windows.Linux.Unix上运行,数据抽取高效 ...
- NET Core迁移
向ASP.NET Core迁移 有人说.NET在国内的氛围越来越不行了,看博客园文章的浏览量也起不来.是不是要转Java呢? 没有必要扯起语言的纷争,Java也好C#都只是语言是工具,各有各的 ...
- .NET Core Blazor 1-Blazor项目文件分析
.NET Core Blazor 1-Blazor项目文件分析 本节内容为Blazor的基本文件 简介 Blazor是一个使用.NET技术用于代替JavaScript/typescript的前端WEB ...
- 【转帖】从 Oracle 到 PostgreSQL ,某保险公司迁移实践 技术实践
从 Oracle 到 PostgreSQL ,某保险公司迁移实践 http://www.itpub.net/2019/11/08/4108/ 信泰人寿保险股份有限公司 摘要:去O一直是金融保险行业永恒 ...
- EntityFramework Core迁移时出现数据库已存在对象问题解决方案
前言 刚开始接触EF Core时本着探索的精神去搞,搞着搞着发现出问题了,后来就一直没解决,觉得很是不爽,借着周末好好看看这块内容. EntityFramework Core迁移出现对象在数据库中已存 ...
随机推荐
- python变量及简单数据类型
python 目录 python 1.变量 1.变量的定义 2.变量的命名 3. 关键字 4.变量的命名规则 5.变量的类型 5.不同类型变量之间的计算 6.变量的输入 7.变量的格式化输出 8.格式 ...
- Docker公共&本地镜像仓库(七)
分发镜像 我们已经会构建自己的镜像了,那么如果在多个docker主机上使用镜像那?有如下的几种可用的方法: 用相同的Dockerfile在其他host上构建镜像 将镜像上传到公共registry(比如 ...
- 2020 计蒜之道 预赛 第三场 石子游戏(简单)(暴力DP)
石子游戏(简单) 原题链接 思路: 通过形式容易看出是一道DP.其中异或和的情况只有64种,所以我们可以开一维来记录当前异或和的状态. 利用dp[当前位置][异或和][是否选择当前]来进行状态转移.时 ...
- Redis5设计与源码分析读后感(四)压缩列表
一.引言 上一节我们总结了跳跃表的知识,我们知道了有序数组可以用跳跃表实现,也可以用压缩列表来实现,这一篇文章我们来总结一下压缩列表相关的知识. 二.压缩列表简介 定义:压缩列表 ziplist 本质 ...
- Linux Wait Queue 等待队列
一.引言 linux 内核的等待队列和进程调度息息相关,进程在某些情况下必须等待某些事件的发生,例如:等待一个磁盘操作的终止,等待释放系统资源,或等待指定的时间间隔. 等待队列实现了在事件上的条件等待 ...
- IDEA2020版最佳优化思路(中文界面)
IDEA优化 基于当前最新版idea 2020.1版本进行设置 设置中文 在idea 2020.1版本后官方是支持中文啦 先上效果图 设置方法 这里需要下载官方的中文包 鼠标悬停提示 效果图 设置方法 ...
- MacOS如何正确配置Idea自带Maven插件的环境变量?(亲测)
背景 安装了IDEA开发工具,想执行Maven的命令.但是又没有通过自己下载Maven的安装包进行安装,只是想直接使用IDEA自带的Maven插件来执行Maven的各种命令.由于刚开始使用macos对 ...
- 给Python IDLE添加行号显示
转载:https://blog.csdn.net/howard2005/article/details/104112297 文章目录一.引出问题1.Spyder编辑Python程序能显示行号2.Pyt ...
- Oracle Database XE 11gR2 自带的用户,新建用户,修改用户密码
操作系统:Windows 10 x64 第一节:下载 Oracle Database XE 11gR2 第二节:安装.验证安装 Oracle Database XE 11gR2 第三节:Oracle ...
- 利用rtklib处理GPS以及北斗数据详解
利用rtklib开源代码处理GPS以及北斗数据详解 在GNSS领域最基础的工作是这些GNSS系统的定位工作,对于绝大多数研究者,自己着手完成这些工作是一个"鸡肋":完全独立设计的话 ...