最近遇到一個奇怪的問題,假設我有一個主要的 Web 專案名稱 Test.Web
,它的專案檔內容如下:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TestWeb.Infrastructure\TestWeb.Infrastructure.csproj" />
</ItemGroup>
</Project>
這邊可以看到他引用了一個外部專案名稱為 TestWeb.Infrastructure
,然後它的專案檔內容如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
接著我在 TestWeb.Infrastructure
專案下建立一個 Class 名稱為 TestController
並放置一個名為Fire
的 Action 如下:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace TestWeb.Infrastructure.Controllers
{
public class TestController : Controller
{
[HttpGet]
public async Task<IActionResult> Fire()
{
return Content("Hello!!!!!");
}
}
}
一切設置好後啟動專案 Test.Web
並發了一個 request 到 https://localhost:5001/Test/Fire
,我得到的回應為 404 找不到網頁(神奇了..我在 2.1 時沒遇過),所以我亂試了一陣子後發現如果我在專案 TestWeb.Infrastructure
的專案檔裡對 Microsoft.AspNetCore.App
添加 Version="2.2.0"
後,如以下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.0"/>
</ItemGroup>
</Project>
重新跑ㄧ次網站再 request ㄧ次 https://localhost:5001/Test/Fire
,疑!? 竟然可以得到正常的回應 Hello!!!!!
,但如果 Version 的參數改成 2.2.1、2.2.2、2.2.3 後,則會出現編譯失敗(NU1605),看起來只有在對 Microsoft.AspNetCore.App
設置成版本為2.2.0 才能達到我預期的回應
是我有漏掉什麼還是 TargetFramework 升級成 netcoreapp2.2 後有什麼設定才造成此問題的? 我目前使用的 SDK 為 2.2.105,我有試過2.2.104 也是一樣會有此問題,我這邊也建立了一個範例,連結為 https://github.com/linmasaki/TestWeb/tree/master
這邊付上我在 Debug 時,發現的一些差異點,如果加上 Version=2.2.0
時,主專案內外總共可以取到20個組件(ApplicationParts數量)
但如果移除 Version=2.2.0
後,則只剩下 10 個(即只剩下主專案自己的 Class 了)
我目前測試真的有這問題,添加版本號可以跑應該不是正常解決方式,因為vs提示這不是建議方式
警告 NETSDK1071 A PackageReference to 'Microsoft.AspNetCore.App' specified a Version of `2.2.0`. Specifying the version of this package is not recommended. For more information, see https://aka.ms/sdkimplicitrefs TestWeb.Infrastructure C:\Program Files\dotnet\sdk\2.2.103\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets 153
我幫你發問在S.O跟.NET FB社群看那邊有沒有高手可以解
因為沒有添加Microsoft.AspNetCore.MVC,cspoj改成以下就可以
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App"/>
<PackageReference Include="Microsoft.AspNetCore.MVC" />
</ItemGroup>
</Project>
假如不想要添加Microsoft.AspNetCore.MVC,可以在Web專案使用
service.AddMvc().AddApplicationPart(typeof(HomeController).Assembly);
嗯嗯,非常感謝您的幫忙及測試,事實上我也有再S.O.發過此問題了,不知道是不是英文太差沒有表達出問題核心的關係,目前得到的回應都沒有幫助就是XD。 這邊也付上我發問的連結
.Net Core - Can't get any reference assembly's controller action when used framework netcoreapp2.2
我這邊也沒得到回應 XD
linmasaki 有人回應了
在Startup.cs ConfigureServices添加
service.AddMvc().AddApplicationPart(typeof(Controller的類別).Assembly);
可以解決問題,但沒辦法只添加參考解決
哈,沒有關係,現階段至少還能先上版號 2.2.0 緩解一下,昨天花了將近一天還去爬了有關 MvcServiceCollectionExtensions 的原始碼,懷疑是不是更新到 2.2.1 以上時有修改了什麼,也是白忙一場就是...
暐翰是可以這樣做沒錯,但通常會這樣做的原因是因為 AddApplicationPart
裡的 Controller 也不在我引用的外部專案裡,有點像是我直接去讀取一個單獨的 Dll 檔,只是我已經在專案 build 前將外部的專案引用進來,正常來說應該是不太需要我在另外加上 AddApplicationPart
這段才對
感覺微軟團隊有修改邏輯導致,可能改成只抓啟動專案的Assembly
linmasaki S.O有高手看出原因是沒有添加Microsoft.AspNetCore.MVC,cspoj改成以下就可以
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App"/>
<PackageReference Include="Microsoft.AspNetCore.MVC" />
</ItemGroup>
</Project>
暐翰嗯嗯,我有注意到,該解法也有點讓我匪夷所思就是,畢竟 Microsoft.AspNetCore.App 就已經包含了Microsoft.AspNetCore.MVC,在引用一次好像也有點多餘就是,另外就是我還發現假設引用外部的專案不只一個時,只要其中一個引用加上版本號 2.2.0 即可,例如主專案如下
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TestWeb.OtherModuleA\TestWeb.OtherModuleA.csproj" />
<ProjectReference Include="..\TestWeb.OtherModuleB\TestWeb.OtherModuleB.csproj" />
<ProjectReference Include="..\TestWeb.OtherModuleC\TestWeb.OtherModuleC.csproj" />
</ItemGroup>
</Project>
只要在 OtherModuleA、B、C 任一個專案裡的 Microsoft.AspNetCore.App 加上版號 2.2.0 後,則其它兩個沒加的類別也都能夠正確被主專案讀到,嗯...頗耐人尋味就是= =
我在想其實專案csproj可以改成以下
這樣更輕量、避免該問題,也可以兼容多版本
但還是沒解釋這次異常原因 XD
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;netcoreapp2.2;</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App"/>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.2'">
<PackageReference Include="Microsoft.AspNetCore.MVC" version="2.2.0"/>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.AspNetCore.MVC" version="2.1.1"/>
</ItemGroup>
</Project>