.NET Framework 專案能改用新版 .csproj 嗎?
| | | 5 | |
從 .NET Framework 升級到 .NET Core/6/8/10,我最有感的開發體驗提升是 .csproj 檔的簡化!
傳統 .csproj 必須正向表列所有專案包含的檔案項目,不管 .aspx/.cs/.js/.css/.png/.jpg... 要逐一列舉才會納入專案範圍,出現在發佈結果。
2016 推出的 .NET Core 改採所謂 SDK 風格專案 (SDK-Style Project),特徵是 .csproj 的 Project XML 元素有 Sdk="Micrsofot.NET.Sdk" 宣告套用的 SDK 類型,而最大革新是改為隱式包含(Wildcard Inclusion),不再需要列舉專案檔案,專案預設會自動納入必要項目(Compile 類:**/*.cs、EmbeddedResource 類:**/*.resx、None:其他一般檔案,並排除 bin、obj 等目錄),開發者可依需要額外加入或排除參考,比傳統做法省事且簡潔許多。
比較二者差異:
| 項目 | 傳統 .csproj | SDK Style .csproj |
|---|---|---|
| 根節點 | ToolsVersion、XML namespace、明確 imports | <Project Sdk="Microsoft.NET.Sdk"> |
| 目標框架 | <TargetFrameworkVersion>v4.8</TargetFrameworkVersion> | <TargetFramework>net48</TargetFramework> |
| 原始碼 | 每個 .cs 都要有 <Compile Include> | 預設自動包含 **/*.cs |
| 資源及一般檔案 | 通常逐一列出 | 透過 glob 自動包含 |
| MSBuild targets | 明確 <Import> | SDK 自動匯入 Sdk.props 與 Sdk.targets |
| 組件資訊 | 通常放在 Properties/AssemblyInfo.cs | 預設由 SDK 自動產生 |
| NuGet | 常使用 packages.config 和 HintPath | 通常使用 <PackageReference> |
| 專案 GUID | 一般必須保留 | 新式專案通常不需要 |
| 多目標框架 | 設定繁複 | 可使用 <TargetFrameworks> |
| 手動維護 | 用 Visual Studio 操作 OK,手動新增、刪除檔案易出現衝突 | 檔案系統通常就是專案內容 |
傳統格式範例:
<Project ToolsVersion="12.0"
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="Controllers\HomeController.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
SDK Style 格式範例
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
</Project>
SDK 風格 .csproj 具備以下優點:
- 不需列舉專案檔案項目,專案檔大幅縮小且變簡潔
- 會依據 SDK 決定編譯行為,不需額外引用 Targets
- 增刪專案項目時不用同步修改 .csproj
- NuGet 參照清單包含在 .csproj 裡 (不再需要 packages.config)
- 支援多目標框架建置
<TargetFrameworks>net48;netstandard2.0</TargetFrameworks>(過去得建多個 .csproj 共用檔案)
由上面出現的 net48,大家可能已經發現了,是的,.NET Framework 專案也可以改用 SDK 風格 csproj! 從 VS2017 開始便支援。
但別高興太早,.NET Framework 專案的 .csproj 是可以轉換成 SDK Style 專案但有限制,主要取決專案是否依賴 Visual Studio 專案功能、Designer 或特殊發佈的 Targets。
不同專案類型的轉成 SDK Style .csproj 的可行性如下:
| .NET Framework 專案類型 | 可轉換性 | 說明 |
|---|---|---|
| Class Library | 適合 | 最容易轉換,並能輕鬆實現多目標 |
| Console Application | 適合 | 選用 Microsoft.NET.Sdk |
| Windows Service | 可行 | 本質為 EXE;安裝流程需另外驗證 |
| WinForms | 可行 | 選用 Microsoft.NET.Sdk 並啟用 UseWindowsForms |
| WPF | 可行 | 選用 Microsoft.NET.Sdk 並啟用 UseWPF |
| 單元測試專案 | 可行 | 需改用對應的 Test SDK/adapter |
| WCF Client/一般 WCF Library | 可行 | Generated Proxy、設定檔及設計工具需驗證 |
| WCF Service Application | 有條件 | 若依賴舊式 Web Application Hosting,問題與 ASP.NET 相同 |
| ASP.NET MVC 5/Web API 2 Web Application | 可能但困難 | 能客製化,但無法簡單轉換 |
| ASP.NET Web Forms Web Application | 可能但困難 | 高度依賴舊 Web 專案系統 |
| ASP.NET Web Site | 不支援 | Web Site 無 .csproj,須先改成 Web Application |
| VSTO/Office Add-in | 不適合 | 依賴 VSTO 專案系統及專用 Targets |
| Workflow Foundation Library | 有條件 | 編譯可能可行,但 Designer/Tooling 常有限制 |
| SharePoint 舊式專案 | 不適合 | 依賴專用 Visual Studio Tooling |
| Portable Class Library | 應遷移 | 建議改成 .NET Standard SDK Style |
評估了一下,手邊的古蹟專案以 ASP.NET MVC 及 ASP.NET Web Site 為大宗,應無緣享用。
SDK-style .csproj files greatly simplify .NET projects with implicit file inclusion, cleaner NuGet references, and easier multi-targeting. While .NET Framework projects can sometimes be converted, support varies by project type, with classic ASP.NET and tooling-heavy projects remaining difficult or unsuitable.
Comments
# by Vinix
手邊正在維護的也是ASP.Net 4.8 Web Forms Web Application,以前評估轉.NET最後也是因為太麻煩所以放棄。
# by Player
專案檔以往不是都會隨著使用的IDE版本 提示是否升級的嗎? 為了避免轉檔失敗 還會幫你複製一份備份的資料夾? 與提供升級成功與否的明細報告 此外,.NET Framework的ASP.NET WebForms想轉 .NET的ASP. NET Core根本上寫法就不一樣了吧 這不是你只改個專案檔使用的SDK版本就能搞定的 只有ASP.NET MVC才比較接近ASP.NET Core MVC才有移植的可能
# by 訪客
那sln 可以嗎
# by Jeffrey
to Player, 這裡說的轉換是 .csproj 改用 SDK Style 版本,.NET Framework 版本不變,沒有要升級 .NET 版本或專案架構。如文章所說,若是 Class Library 很適合切換,Web Form 跟 IDE 綁太緊,很難。
# by SHIH HUNG YANG
學到新了新知識,但目前已經在評估改用 VS CODE + AI 撰寫除錯,在開 VS 2010、 2017 IDE 跑測試,或乾脆直接裝 IIS 測試.. 複雜的程式碼管理與 30年的技術債已經想放推了...