修复迁移后 Net Standard 项目中的错误
接上一章, 项目编译结果如下:
解决依赖 dll 引用
在 Net Framework 项目的引用如下:
各引用和作用:
log4net(1.10.0.0) 用于写框架日志
Castle.DynamicProxy(1.1.5.1) 用于代理类生成
Micosoft.Practice.EnterpiseLibrary 微软企业库, 用于管理数据链接和缓存的功能
System.Data.OracleClient 用于链接 Oracle 数据库
System.Data 用于 SQL SERVER ,OLeDB,ODBC 的数据库操作
这些老的项目引用是不能直接用在 Net Standard 项目上的, 解决过程如下:
[解决] log4net 是开源项目, 从 2.0.6 版开始就已经支持. NET Core, 目前是 2.0.8, 在在开源网站和 nuget 上可以下载到. 通过 nuget 引用最新的 dll, 可以无缝兼容
[解决] Castle.DynamicProxy 也是一个开源的项目, 他也具有. NET Core 版本对应的 DLL(Castle.Core), 只是接口和我引用的 1.1.5.1 的接口有一点点区别, 可以调整一点代码解决, 同时把老项目的 dll 也引用最新的 dll 即可.
[移除相关的代码]Micosoft.Practice.EnterpiseLibrary 企业库微软已经很早不支持了, 也没有对应的 Core 版本, 我的做法是检查下代码看看这些代码是否能去掉, 或用别的方式来实现.
System.Data.OracleClient Net Core 官方没有出 dll 来实现, 但是有社区已经实现了对应的 dll. 目前我没有验证这个功能, 只是将相关的类不编译.
System.Data 这个参考下面的章节, 来解决, 因为之前这个 dll 包含了 oledb,odbc,sqlserver 的数据库. 目前微软有 Syste.Data.SqlClient.dll 来兼容 sql server 的其他的都不支持.
新项目的引用截图:
数据库相关的错误修订
MS Sql Server
Net 和 MS Sql Server 交互大多通过 Syste.Data.SqlClient.dll 中相关类操作, 在 Core 项目中, 项目中通过引用 Nuget 中的 System.Data.SqlClient 包, 即可修复.
OleDB 和 ODBC
Net Core\Standard 不再支持 System.Data.OleDb.
目前没有找到相关 Net Core\Standard 中官方有相关的类库来替代.
所以在编译 Net Core\Standard 项目时, 通过项目文件去除相关类.
移除编译的方式很简单, 使用文本编辑器, 打开. csproj 文件:
之前我们通过添加一下配置, 将代码以快捷方式添加到新项目中
- <ItemGroup>
- <Compile Include="..\..\Beyondbit.Framework\**\*.cs" />
- </ItemGroup>
将我们不需要的功能排除掉, 使用以下语法:
- <ItemGroup>
- <Compile Remove="..\..\Beyondbit.Framework\Data\OdbcDbClientProvider.cs" />
- <Compile Remove="..\..\Beyondbit.Framework\Data\OleDbDbClientProvider.cs" />
- </ItemGroup>
通过上面, 新项目中, 就不会出现 OdbcDbClientProvider.cs 文件, 而老项目还有的. 通过这种方式排除和 olddb 和 odbc 相关的类.
Oracle
Net Core\Standard 不再支持 System.Data.OracleClient.
微软没有提供相关类库来支持, 但是有开源社区有实现的版本 OracleClientCore https://github.com/ericmend/oracleClientCore-2.0 , 可以在 Nuget 中下载, 这个我没有试过是否有效.
修复配置文件读取的错误
web.config App.config
在 Net Core 2.0 以后是支持 App.config 的, 在之前 Net Core 中的配置不能像我们在 Net Frameword 中那样读取配置. 2.0 之前 Net Core 读取配置的方法, 可以参考 LizeZere 同学的文章ASP.NET Core 开发 - 读取配置文件 Configuration和晓晨 Master 同学的文章.NET Core 配置 Configuration 杂谈
在 Net Core\Standard 中是没有 web.config 的概念, No ConfigurationManager in ASP.NET Core, 没错. net core 不支持了.
不过可以采取变通的方式来解决, 参考 binbinxu 同学的文章解决.NET CORE 2.0 踩坑记录之 ConfigurationManager, 验证是有效的.
App.config 读取 BUG
实测使用 System.Configuration.ConfigurationManager 4.4.1 版本读取配置时, 在 Web 项目或者控制台应用, 都可以顺利读取. 但我在 vs2017 创建的 MSUnit 的测试项目运行集成测试时, 读取失败了. 目前还没找到方法解决, 后续我会反馈 BUG 在 github 上.
编译时报 "CS0579: Duplicate'AssemblyFileVersionAttribute'attribute" 错误的解决办法
当创建 .NET Core/Standard 2.0 项目时, VS 不会像. NET Framework 项目一样自动生成 AssemblyInfo.cs 文件.
而且, 若是手工在项目中加入以前写好的 AssemblyInfo.cs 文件, 编译时会报告 "CS0579: Duplicate'AssemblyFileVersionAttribute'attribute" 错误.
参考 zyl910 同学的文章解决, 验证有效.
修复 HttpContext 问题
在我们的老项目, 代码里面可能会判断当前是否在 Web 环境下, 会读取一些以前特定的代码, 这个问题是最难处理的. 如以下代码:
可以看到编译提示 HttpContext 在老项目可以, 在新项目显示不可用, 并出现红线. 这是因为在 NetCore 中 System.Web 的命名空间不在包含 HttpContext 类了. 通过查询一些文章, 有很多的文章都描述了如何在 Net Core 下, 模拟 HttpContext.Current 的. 如:
在. net Core 中像以前那样的使用 HttpContext.Current
ASP.NET Core 开发之 HttpContext
等等文章.
但是它们都提到了需要在 Startup 类通过 ioc 注入东西, 我的项目只是一个类库, 他可以运行在任何环境下, 我该如何在类库中使用 HttpContext, 并且我不想更改代码. 搜索了国内和国外的网站, 都没有一个很好的方案. 我自己琢磨了一个临时的方案:
在 Nuget 引用 Microsoft.AspNetCore.Http 库, 这是 net core 中 HttpContextBase 的库
在我的新项目类顶级命名空间下, 创建一个静态类叫 HttpContext, 里面具有一个 Current 的属性, 返回 NetCore 中的 HttpContext, 代码如下:
- using Microsoft.AspNetCore.Http;
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace Beyondbit.Framework
- {
- public class HttpContext
- {
- private static IHttpContextAccessor _accessor;
- public static Microsoft.AspNetCore.Http.HttpContext Current => _accessor.HttpContext;
- public static void Configure(IHttpContextAccessor accessor)
- {
- _accessor = accessor;
- }
- }
- }
修改代码将 System.Web.HttpContext.Current 这样的代码改成 HttpContext.Current 并引用 System.Web 命名空间
这样同样的代码即可在老项目编译通过, 同时新项目也能编译通过
目前这样是可以编译通过, 但是 HttpContext.Current 是 null. 需要在 mvc core 项目中的 Startup 类中, 调用一下 Beyondbit.Framework.HttpContext.Configure()方法, 将 httpConetxt 的注入到类库中
HttpContext.Current.Session 问题
Net Core 中的 Session 类和 Net Framework 的类变动非常的大, 而且接口都已经变更, 比如在 Net Framework 中 HttpContext.Current.Session["Key"] 来获取一个 object 类型的变量, 但是在 Net Core 中这样是不行的, Session 已经不支持 [] 的写法, HttpContext.Current.Session.TryGetValue, 或者扩展方法 HttpContext.Current.Session.Get, 但这个接口默认返回的是 byte[]类型, 或者 HttpContext.Current.Session.GetString 这样的方法获取.
这样的代码已经和 Net Framework 无法兼容.
目前无奈的做法是:
修改代码去除 session 的读取, 这个需要根据具体功能来调整, 不能一概去除, 要不然影响原来的功能
通过条件编译, 来使得 net core 项目不支持这些功能, 而老项目编译时依然支持, 在新项目中添加条件编译的标志 NETSTANDARD2_0, 然后典型的代码如下:
- if (HttpContext.Current == null)
- return "";
- #if NETSTANDARD2_0
- throw new NotSupportedException();
- #else
- return HttpContext.Current.Session.SessionID;
- #endif
NotSupportedException 类是我添加的一个异常类, 用来在遇到我们想项目时调用了一些我们临时去掉的功能, 可以很明显告诉我们代码的问题在哪里
SqlCommandBuilder
目前这个类只能利用条件编译先解决.
编译结果已经全部 OK 了, 可以看到我的编译结果
总结:
第二步的工作是来消灭错误, 目前已经全部完成, 第三步是迁移单元测试和集成测试项目, 以及最终的多个平台运行的测试.
来源: https://www.cnblogs.com/xakoy/p/8891375.html