日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

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

發布時間:2023/12/4 asp.net 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 将 ASP.NET Core 2.1 升级到最新的长期支持版本ASP.NET Core 3.1 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 前言

  • Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 消失了

  • 升級到 ASP.NET Core 3.1

  • 項目文件(.csproj)

  • Program.cs

  • Startup.cs

  • ViewBag 與 Razor Pages 第一次接觸

  • ViewBag 與 Razor Pages 第二次接觸

  • 小結(文件更改對比圖)

  • ASP.NET Core 3.1的確很棒,肉眼可見的快、快、快!

  • ?前言

    2019年的最后一個月,微軟終于發布了.Net Core 3.1,這是 .Net Core 有史以來的第二個長期支持版本(至少 3 年的支持期限)。

    作為一個大版本更新,.NET Core 3.0 引入了大量改進和新特性,例如新增加的 Windows Forms 和 WPF、新的 JSON API、對 ARM64 架構的支持,以及全面提升的性能。

    所以升級是勢在必行的,那么很多開發人員就面臨一個問題:

    如果從上一個長期支持版本?ASP.NET Core 2.1 升級到最新的?ASP.NET Core 3.1 ?

    ?.Net Core 版本列表:

    From:https://dotnet.microsoft.com/download/dotnet-core

    ?

    如果是之前的 .Net Framework,這個升級是非常平滑的,甚至不需要做任何改動(比如:.Net Framework 2.0 -> .Net Framework 4.5),但是 .Net Core 的升級卻有點麻煩,微軟給出了一系列的升級指南,不過都是從上一個版本到下一個緊鄰版本:

    ASP.NET Core 2.1 -> 2.2:https://docs.microsoft.com/zh-cn/aspnet/core/migration/21-to-22

    ASP.NET Core 2.2 -> 3.0:https://docs.microsoft.com/zh-cn/aspnet/core/migration/22-to-30

    ASP.NET Core 3.0 -> 3.1:https://docs.microsoft.com/zh-cn/aspnet/core/migration/30-to-31?

    當然這個過程不僅僅是改個配置文件的問題,.Net Core 的版本升級中居然有很多 Breaking changes,也就是說如果你用的類在 .Net Core 3.1 中突然刪除了,對不起,你只有調整自己代碼的份了。?

    Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 消失了

    而且這個?Breaking changes 還不少,比如 FineUICore 之前的版本(支持ASP.NET Core 2.1)用到的 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 在 .Net Core 3.1 就被無情的刪掉了:

    ?

    那位說了,你為啥要用 .Internal 里面的類?

    這是很正常的,FineUICore作為一個支持 ASP.NET Core 的控件庫,需要一些底層操作,為了支持快速數據綁定,類似如下的形式:

    • 支持 TagHelpers 的頁面代碼:<f:DatePicker For="TheModel.StartDate"></f:DatePicker>

    • 支持 HtmlHelpers 的視圖代碼:F.DatePickerFor(m => m.TheModel.StartDate)

    可以參考示例:https://pages.fineui.com/#/DataModel/UICompare

    為了支持這個特性,我們就需要計算表達式的文本值,以及表達式所綁定的數據,因此就用到了如下兩個靜態類方法:

    • ExpressionHelper.GetExpressionText

    • ExpressionMetadataProvider.FromLambdaExpression

    在 .Net Core 2.2 之前的版本,這兩個方法是逃不過的。可惜不巧的是,微軟卻認為這些方法沒有公開的價值,因此就武斷的隱藏掉了(你讓之前使用這些類的程序情何以堪!)。

    網絡上有很多類似的提問,但是阻擋不了微軟隱藏幾乎所有 .Internal 命名空間類的做法。

    https://github.com/aspnet/AspNetCore/issues/8678

    https://github.com/aspnet/Mvc/issues/8724

    ?

    在 ASP.NET Core 3.1 雖然有替代的方法可以實現上述被刪掉的功能,但是就做不到向后兼容了。FineUICore近期已經升級到 FineUICore v6.2.0,以便適用這個改動,升級之后支持 .Net Core 3.1+,不再對老版本提供支持了。

    ?

    升級到?ASP.NET Core 3.1

    下面我們會以 FineUICore.Examples 為例,講解如果將?ASP.NET Core 2.1 升級到?ASP.NET Core 3.1,這里面的坑還真不少。

    項目文件(.csproj)

    ?

    這里面有幾點需要注意:

    1. TargetFramework 改為 netcoreapp3.1

    2. 刪除 Microsoft.AspNetCore.App 的引用,這個會默認包含在框架 Sdk=Microsoft.NET.Sdk.Web 中

    3. 添加?Microsoft.AspNetCore.Mvc.NewtonsoftJson 的引用

    ?

    有一點需要特別注意, .Net Core 3.0 已經從共享框架中刪除了?Newtonsoft.Json,并引入新的 System.Text.Json 類庫。

    但是我們的 FineUICore 示例代碼很多地方都依賴了?Newtonsoft.Json 的特性,因此需要引入 Microsoft.AspNetCore.Mvc.NewtonsoftJson,這個引用會自動包含?Newtonsoft.Json 庫,可以求證于編譯時的 Debug 文件夾,位于項目的?\bin\Debug\netcoreapp3.1:

    ?完整的項目工程文件:

    <Project Sdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>netcoreapp3.1</TargetFramework><MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0" /></ItemGroup><ItemGroup><ProjectReference Include="..\FineUICore\FineUICore.csproj" /></ItemGroup></Project>

    Program.cs

    需要注意的幾點:

    1. 將?IWebHostBuilder 改為??IHostBuilder

    2. 將 Web 服務器的啟動代碼放到?ConfigureWebHostDefaults 中

    ?

    當然,這些改動我們不需要特別關心,簡單的照做就行了。

    完整的 Progam.cs 代碼:

    using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging;namespace FineUICore.Examples {public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});} }

    Startup.cs

    這里的改動有點多,我們分兩個截圖分別說明?ConfigureServices 和?Configure 的改動:

    ?

    這里有幾點需要調整:

    1. 用?AddControllersWithViews 替代 AddMvc

    2. 對參數?ModelBinderProviders 更改放到 AddMvcOptions 中

    3. 添加 AddNewtonsoftJson 用來使用老的?Newtonsoft.Json 來序列化 JSON 數據

    ?

    ASP.NET Core 3.1 添加了三個新的服務注冊方法來代替之前的 AddMvc:

    • AddRazorPages:添加對 Razor Pages 的支持

    • AddControllersWithViews:添加對控制器和視圖的支持

    • AddControllers:添加對控制器的支持

    這些方法可以組合,比如如下代碼等效于之前版本的 AddMvc:

    services.AddControllersWithViews(); services.AddRazorPages();

    這個方法的完整代碼:

    public void ConfigureServices(IServiceCollection services) {services.AddDistributedMemoryCache();services.AddSession();// 配置請求參數限制services.Configure<FormOptions>(x =>{x.ValueCountLimit = 1024; // 請求參數的個數限制(默認值:1024)x.ValueLengthLimit = 4194304; // 單個請求參數值的長度限制(默認值:4194304 = 1024 * 1024 * 4)});// FineUI 服務services.AddFineUI(Configuration);services.AddControllersWithViews().AddMvcOptions(options =>{// 自定義模型綁定(Newtonsoft.Json)options.ModelBinderProviders.Insert(0, new JsonModelBinderProvider());}).AddNewtonsoftJson(); }

    下面來看下 Configure 方法:

    這里面有幾點重要改動:

    1. 將?IHostingEnvironment 改為?IWebHostEnvironment

    2. 添加?app.UseRouting();app.UseAuthorization();,注意添加的位置,要放到 UseStaticFiles 的后面

    3. UseMvc 改為 UseEndpoints

    完整的函數代碼:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");}app.UseStaticFiles();app.UseSession();app.UseRouting();app.UseAuthorization();// FineUI 中間件(確保 UseFineUI 位于 UseEndpoints 的前面)app.UseFineUI();app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(name: "area",pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");});}

    對于支持 Razor Pages 的項目,這里的 UseEndpoints 代碼要改為:

    app.UseEndpoints(endpoints => {endpoints.MapRazorPages(); });

    ?

    ViewBag 與 Razor Pages 第一次接觸

    在傳統的 Controller/Model/View 的 MVC 架構中,我們可以在控制器中使用 ViewBag 將數據傳遞到 視圖中,雖然 ViewBag 只是字典類 ViewData 的一個動態封裝,但是寫法更簡單:

    然而在 Razor Pages 的頁面模型類中,卻少了對 ViewBag 的支持,因此在 ASP.NET Core 2.2 之前的版本里,我們通過在基類中新增一個 ViewBag 屬性來解決:

    可以看出,這里的 ViewBag 其實是一個 dynamic 類型,內部存儲單元還是 ViewData,這段代碼來自:https://forums.asp.net/t/2128012.aspx?Razor+Pages+ViewBag+has+gone+

    ?

    這么一個看似很技巧的東西其實來自微軟某位程序員的自(zi)信(da),如果你留意觀察,就會發現一個奇怪的邏輯:

    • Controller 基類 和 View 視圖中支持 ViewBag

    • Razor Pages的后臺模型類中不支持 ViewBag,然后 Razor Pages的頁面中支持 ViewBag

    說白了,微軟的邏輯是:你可以在?Razor Pages 中使用 ViewBag(盡管也可以設置) ,但是別在模型類中設置 ViewBag。

    ?

    這位大蝦(DamianEdwards)在一個 Github 的 issue 中提到這樣一個觀點:

    We purposefully didn't add ViewBag because I wanted to discourage its use. As @pranavkm points out you can add it back easily enough if you wish but I don't have plans to add it back to the built-in base class.

    原文:https://github.com/aspnet/Mvc/issues/6754?

    我帶點感情色彩的翻譯一下哈:

    我就看 ViewBag 不順眼了,所以故意不添加 ViewBag。并且我也不準備在以后的版本中把 ViewBag 加回來,你非要用的話自己弄吧!

    在另一個回復中,DamianEdwards提到了 ViewBag 可能有性能問題:

    ViewBag uses dynamic which in our testing introduces a measurable performance impact on the processing of pages or views that use it.

    不過,這個決定權不能留給用戶自己嗎?如果我只是想通過 ViewBag 傳遞兩三個數據,絕對不會遇到什么性能問題,并且這應該是 90% 的應用場景。

    ?

    最終,吐槽歸吐槽,代碼是你寫的,你想咋搞就咋搞。

    ?

    ViewBag 與 Razor Pages 第二次接觸

    然而,在升級到 ASP.NET Core 3.1 之后,這個地方又報錯了。

    原因我們前面提過,對 ViewBag 的封裝用到了 DynamicViewData,這個類是定義在?Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 里面的。而在 ASP.NET Core 3.1 中,微軟刪除 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 的公開訪問權限。

    ?

    在實際項目中,我們還是要遵循微軟的建議,使用 ViewData 而不是 ViewBag。

    然而我們的 FineUICore 示例項目有 750 多個頁面,很多地方都用到了 ViewBag,為了和之前的版本兼容,我們還是要把 ViewBag 找回來。

    既然 DymaicViewData 不見了,就自己創建一個?DymaicViewData:

    public class DynamicViewData : DynamicObject {private ViewDataDictionary ViewData;public DynamicViewData(ViewDataDictionary viewData){ViewData = viewData;}/// <summary>/// 獲取所有key/// </summary>public override IEnumerable<string> GetDynamicMemberNames(){return ViewData.Keys;}/// <summary>/// 調用 ViewBag.key; 時執行/// </summary>public override bool TryGetMember(GetMemberBinder binder, out object result){result = ViewData[binder.Name];return true;}/// <summary>/// 調用 ViewBag.key = "value"; 時執行/// </summary>public override bool TrySetMember(SetMemberBinder binder, object value){ViewData[binder.Name] = value;return true;} }

    在后臺模型類基類中,調用方法改為:

    private DynamicViewData _viewBag;public dynamic ViewBag {get{if (_viewBag == null){_viewBag = new DynamicViewData(ViewData);}return _viewBag;} }

    小結(文件改動對比圖)

    綜上所述,升級到 ASP.NET Core 3.1 主要改動三個項目文件,其他地方基本沒有變化。

    為了更直觀的查看這三個文件的改動,我們做了下面三幅對比圖片(以FineUICore.EmptyProject項目為例)。

    1. 項目工程文件(FineUICore.EmptyProject.csproj)

    ?

    2.?Program.cs

    ?

    3. Startup.cs

    ?

    ?

    ASP.NET Core 3.1的確很棒,肉眼可見的快、快、快!

    剛把 FineUICore 的官網示例部署到服務器時,管理員是這么給我說的:

    ?

    之前一直沒有注意,看來 ASP.NET Core 的性能的確是要好一些。

    我對比了 FineUIPro(WebForms) 和 FineUICore(ASP.NET Core) 的在線示例網站,發現 ASP.NET Core 3.1 的確比 WebForms 快多了。

    肉眼可見的快、快、快,下面兩個動畫圖片可見一斑:

    ?

    https://pro.fineui.com/

    ?

    ?

    ?

    https://core.fineui.com/

    ?

    這兩個站點部署在同一臺服務器的同一個IIS里面,為了便于區分,FineUICore(ASP.NET Core)為深色主題,FineUIPro(WebForms)為淺色主題。?

    注:由于是共享服務器,所以服務器資源在不同時刻會有變化,并且網絡環境也是不斷變化的,可以在同一時刻(測試間隔小于1s)多次測試兩個網站。?

    當然每個人測出來的結果會不盡相同,歡迎分享你的測試截圖....?

    ?

    總結

    以上是生活随笔為你收集整理的将 ASP.NET Core 2.1 升级到最新的长期支持版本ASP.NET Core 3.1的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。