將 Net 項目升級 Core項目經驗:(二)修復遷移後Net Standard項目中的錯誤

修復遷移後Net Standard項目中的錯誤

接上一章,項目編譯結果以下: imagehtml

解決依賴dll引用

在Net Framework項目的引用以下: imagegit

各引用和做用:github

  • 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項目上的,解決過程以下:web

  • [解決] 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的其餘的都不支持。

新項目的引用截圖: imagesql

數據庫相關的錯誤修訂

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文件: 以前咱們經過添加一下配置,將代碼以快捷方式添加到新項目中session

<ItemGroup>
    <Compile Include="..\..\Beyondbit.Framework\**\*.cs" />
  </ItemGroup>

將咱們不須要的功能排除掉,使用如下語法:mvc

<ItemGroup>
    <Compile Remove="..\..\Beyondbit.Framework\Data\OdbcDbClientProvider.cs" />
    <Compile Remove="..\..\Beyondbit.Framework\Data\OleDbDbClientProvider.cs" />
 </ItemGroup>

經過上面,新項目中,就不會出現OdbcDbClientProvider.cs文件,而老項目還有的。經過這種方式排除和olddb和odbc相關的類。oracle

Oracle

Net Core\Standard再也不支持System.Data.OracleClient。 微軟沒有提供相關類庫來支持,可是有開源社區有實現的版本OracleClientCore ,能夠在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環境下,會讀取一些之前特定的代碼,這個問題是最難處理的。如如下代碼: image 能夠看到編譯提示HttpContext在老項目能夠,在新項目顯示不可用,並出現紅線。這是由於在NetCore中System.Web的命名空間不在包含HttpContext類了。經過查詢一些文章,有不少的文章都描述瞭如何在Net Core下,模擬HttpContext.Current的。如:

等等文章。
可是它們都提到了須要在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沒法兼容。

目前無奈的作法是:

  1. 修改代碼去除session的讀取,這個須要根據具體功能來調整,不能一律去除,要否則影響原來的功能
  2. 經過條件編譯,來使得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了,能夠看到個人編譯結果

image

總結: 第二步的工做是來消滅錯誤,目前已經所有完成,第三步是遷移單元測試和集成測試項目,以及最終的多個平臺運行的測試。

相關文章
相關標籤/搜索