.NET 5 + 自定义 appsettings.json - SPA 默认页面中间件无法 return 默认页面

.NET 5 + Custom appsettings.json - The SPA default page middleware could not return the default page

我有一个带有 ReactJS 的 C# .NET5 项目(C# 项目的 VS 项目模板)。

如果我不更改 appsettings.jsonlaunchSettings.json 一切正常(localhost DEV 和 TEST我通过发布发送应用程序的服务器)。

在 ASP.NET MVC5 (.NET Framework) 中,我使用 Publish 按钮,在切换 Debug 或 Release 之后,我有 web.config 与 web.Release.config 相同的后缀,在这个文件中我有 Release DB 的配置。

现在在 .NET 5 中,我想要更多 appsettings 文件,其中包含差异配置(家庭、工作、承包商、测试、 Prod),仅用于开关配置名称(运行 VS 中的名称),它已定义并与 launchSettings.json 连接,现在我必须在 diff PC 上注释所选的 ConnectionString机器上的数据库

而且我还喜欢 Publish 主可运行项目中的按钮仅加载 appsettings.Prod.json 到生产服务器

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

        Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();

        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseSerilog()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

appsettings.json

{
  "Serilog": {
    "Using": [],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "Logs\AuditInfo-.log",
          "rollingInterval": "Day", // Rolling Interval
          "outputTemplate": "{Timestamp:dd.MM.yyyy HH:mm:ss} [{Level}] ({ThreadId}) - {Message}{NewLine}{Exception}"
        }
      }
    ]

  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=home;Initial Catalog=test;Integrated Security=True;"
    //"DefaultConnection": "Data Source=test;Initial Catalog=test;Integrated Security=True;"
    //"DefaultConnection": "Data Source=work;Initial Catalog=test;Integrated Security=True;"
    //"DefaultConnection": "Data Source=contractor;Initial Catalog=test;Integrated Security=True;"
  }
}

appsettings.Development.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

launchSettings.json

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:53806",
      "sslPort": 44348
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Search": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

我默认有这些appsettings.___.json文件

如果我添加新的 appsettings.Dev.json 并编辑 launchSettings.json 如:

launchSettings.json

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:53806",
      "sslPort": 44348
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Dev": { // NEW RUN option with connect to Dev appsettings file
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Dev"
      }
    },
    "Test": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

appsettings.Dev.json

{
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=dev;Initial Catalog=dev;Integrated Security=True;"
  }
}

我只得到 HTTP 500 响应,在日志中我得到这个 错误:

02.04.2021 19:27:57 [Error] (6) - An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The SPA default page middleware could not return the default page '/index.html' because it was not found, and no other middleware handled the request.

   at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>c__DisplayClass0_0.<Attach>b__1(HttpContext context, Func`1 next)
   at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_1.<Use>b__1(HttpContext context)
   at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_2.<Use>b__2()
   at Microsoft.AspNetCore.SpaServices.SpaDefaultPageMiddleware.<>c__DisplayClass0_0.<Attach>b__0(HttpContext context, Func`1 next)
   at Microsoft.AspNetCore.Builder.UseExtensions.<>c__DisplayClass0_1.<Use>b__1(HttpContext context)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)

主要问题在Startup.csenv.IsDevelopment()如果我评论条件,一切正常很好(对于 Dev,我使用 IISExpress):

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";

            //if (env.IsDevelopment())
            //{
                spa.UseReactDevelopmentServer(npmScript: "start");
            //}
        });

是否可以注册另一个ASPNETCORE_ENVIRONMENT变量然后开发并与函数一起使用env.IsDevelopment() ?或者还有其他方法吗?

env.IsDevelopment()只有在ASPNETCORE_ENVIRONMENT is Development时才是true。不过还有其他选择:

  1. 使用env.IsEnvironment('some_env')
  2. 编写自己的扩展 - here is the source for env.IsDevelopment