用 Visual Studio 建了一個 ASP.NET Core 專案跑不起來,試了用 dotnet new 新建也是如此,錯誤訊如下:

X:\MyTest\EmptyWeb>dotnet run
Building...
Unhandled exception. System.InvalidOperationException: Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both.
   at Microsoft.AspNetCore.Server.Kestrel.Core.LocalhostListenOptions..ctor(Int32 port)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.ParseAddress(String address, Boolean& https)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IEnumerable`1 listenOptions, AddressBindContext context, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.BindAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerImpl.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Microsoft.AspNetCore.Builder.WebApplication.Run(String url)
   at Program.<Main>$(String[] args) in X:\MyTest\EmptyWeb\Program.cs:line 6

Dynamic port binding is not supported when binding to localhost. You must either bind to 127.0.0.1:0 or [::1]:0, or both. 錯誤訊息無比明確,但 Google 結果只有一筆,還是 Github 某個 Kooboo.HttpServer 專案原始碼中的錯誤訊息定義:

第一次遇到這種詭異狀況,難道全世界只有我一個人遇到這個問題?

查詢 ASP.NET Core 原始碼,在 aspnetcore/src/Servers/Kestrel/Core/src/CoreStrings.resx 找到 DynamicPortOnLocalhostNotSupported 定義相同訊息的字串(筆記:所以 Google 不是所有公開連結都搜得到),再進一步追到內部物件 LocalhostListenOptions 會在傳入 localhost:0 時噴錯:

internal sealed class LocalhostListenOptions : ListenOptions
{
    internal LocalhostListenOptions(int port)
        : base(new IPEndPoint(IPAddress.Loopback, port))
    {
        if (port == 0)
        {
            throw new InvalidOperationException(CoreStrings.DynamicPortOnLocalhostNotSupported);
        }
    }
   //...略....

回頭檢查 EmptyWeb\Properties\launchSettings.json 果真出現 ℎttp://localhost:0! 比對正常專案應該要類似 "applicationUrl": "ℎttps://localhost:7238;ℎttp://localhost:5000",為什麼會出現 localhost:0 是個謎:

接著一陣胡亂操作,更新 Visual Studio 版本初試沒用,但再重開機問題便消失。由於無法重現錯誤,也就無法再調查,筆記備忘。

至於為什麼 localhost 不支援動態 Port,但 127.0.0.1、::1 可以?我猜測是因為 localhost 同時代表 127.0.0.1 跟 ::1,各自的可用 Port 不同,難以動態決定 Port (理論上還是可能,但複雜度較高)。在 AddressBinder.ParseAddress 有一段註解,就當成佐證吧:

        else if (string.Equals(parsedAddress.Host, "localhost", StringComparison.OrdinalIgnoreCase))
        {
            // "localhost" for both IPv4 and IPv6 can't be represented as an IPEndPoint.
            options = new LocalhostListenOptions(parsedAddress.Port);
        }


Comments

# by ByTim

我遇過程式碼更新後,本機的畫面永遠舊版的,建置、重建、IIS關閉重啟都一樣,偵錯模式倒是新版的,最後重開機才正常。

Post a comment