解决 ASP.NET Core 项目Troubleshoot ASP.NET Core projects

作者:Rick AndersonBy Rick Anderson

以下链接提供的故障排除指南:The following links provide troubleshooting guidance:

.NET Core SDK 警告.NET Core SDK warnings

安装.NET Core SDK 的 32 位和 64 位版本Both the 32-bit and 64-bit versions of the .NET Core SDK are installed

新项目对话框为 ASP.NET Core,你可能会看到以下警告:In the New Project dialog for ASP.NET Core, you may see the following warning:

安装了.NET Core sdk 的 32 位和 64 位版本。Both 32-bit and 64-bit versions of the .NET Core SDK are installed. 仅从安装在 64 位版本的模板 c:\Program Files\dotnet\sdk\会显示。Only templates from the 64-bit versions installed at 'C:\Program Files\dotnet\sdk\' are displayed.

时,此警告会出现 (x86) 32 位和 64 位 (x64) 版本的.NET Core SDK安装。This warning appears when both 32-bit (x86) and 64-bit (x64) versions of the .NET Core SDK are installed. 可能安装这两个版本的常见原因包括:Common reasons both versions may be installed include:

  • 你最初下载.NET Core SDK 安装程序使用 32 位计算机,但然后复制它跨并安装在 64 位计算机上。You originally downloaded the .NET Core SDK installer using a 32-bit machine but then copied it across and installed it on a 64-bit machine.
  • 由另一个应用程序安装了 32 位.NET Core SDK。The 32-bit .NET Core SDK was installed by another application.
  • 下载并安装了错误的版本。The wrong version was downloaded and installed.

卸载 32 位.NET Core SDK,以防止出现此警告。Uninstall the 32-bit .NET Core SDK to prevent this warning. 从卸载Control Panel > 程序和功能 > 卸载或更改程序Uninstall from Control Panel > Programs and Features > Uninstall or change a program. 如果您了解为何会出现的警告和其影响,则可以忽略该警告。If you understand why the warning occurs and its implications, you can ignore the warning.

.NET Core SDK 的安装在多个位置The .NET Core SDK is installed in multiple locations

新项目对话框为 ASP.NET Core,你可能会看到以下警告:In the New Project dialog for ASP.NET Core, you may see the following warning:

.NET Core SDK 安装在多个位置中。The .NET Core SDK is installed in multiple locations. 仅在安装的 Sdk 中的模板 c:\Program Files\dotnet\sdk\会显示。Only templates from the SDKs installed at 'C:\Program Files\dotnet\sdk\' are displayed.

外部的一个目录中有至少一个安装的.NET Core SDK 时,将显示此消息c:\Program Files\dotnet\sdk\You see this message when you have at least one installation of the .NET Core SDK in a directory outside of C:\Program Files\dotnet\sdk\. 这通常发生在使用复制/粘贴,而不 MSI 安装程序的计算机上部署了.NET Core SDK 时。Usually this happens when the .NET Core SDK has been deployed on a machine using copy/paste instead of the MSI installer.

卸载所有 32 位.NET Core Sdk 和运行时以防止出现此警告。Uninstall all 32-bit .NET Core SDKs and runtimes to prevent this warning. 从卸载Control Panel > 程序和功能 > 卸载或更改程序Uninstall from Control Panel > Programs and Features > Uninstall or change a program. 如果您了解为何会出现的警告和其影响,则可以忽略该警告。If you understand why the warning occurs and its implications, you can ignore the warning.

检测到没有.NET Core SdkNo .NET Core SDKs were detected

  • 在 Visual Studio新的项目对话框适用于 ASP.NET Core,可能会看到以下警告:In the Visual Studio New Project dialog for ASP.NET Core, you may see the following warning:

    检测到任何.NET Core Sdk,请确保将它们包括在环境变量PATHNo .NET Core SDKs were detected, ensure they are included in the environment variable PATH.

  • 执行时dotnet命令时,警告显示为:When executing a dotnet command, the warning appears as:

    无法找到任何已安装的 dotnet Sdk。It was not possible to find any installed dotnet SDKs.

这些警告显示时的环境变量PATH没有指向计算机上任何.NET Core Sdk。These warnings appear when the environment variable PATH doesn't point to any .NET Core SDKs on the machine. 若要解决此问题:To resolve this problem:

  • 安装 .NET Core SDK。Install the .NET Core SDK. 获取从最新的安装程序.NET 下载Obtain the latest installer from .NET Downloads.
  • 确认PATH环境变量指向 SDK 安装的位置 (C:\Program Files\dotnet\为 64 位 x64 或C:\Program Files (x86)\dotnet\为 32 位 x86)。Verify that the PATH environment variable points to the location where the SDK is installed (C:\Program Files\dotnet\ for 64-bit/x64 or C:\Program Files (x86)\dotnet\ for 32-bit/x86). 在 SDK 安装程序通常设置PATHThe SDK installer normally sets the PATH. 始终在同一台计算机上安装相同的位数 Sdk 和运行时。Always install the same bitness SDKs and runtimes on the same machine.

安装.NET Core 托管捆绑包后缺少 SDKMissing SDK after installing the .NET Core Hosting Bundle

安装.NET Core 托管捆绑包修改PATH时,它会安装.NET Core 运行时指向 32 位 (x86) 版本的.NET Core (C:\Program Files (x86)\dotnet\)。Installing the .NET Core Hosting Bundle modifies the PATH when it installs the .NET Core runtime to point to the 32-bit (x86) version of .NET Core (C:\Program Files (x86)\dotnet\). 这可能导致缺少 Sdk 时 32 位 (x86) 的.NET Coredotnet使用命令 (检测到任何.NET Core Sdk)。This can result in missing SDKs when the 32-bit (x86) .NET Core dotnet command is used (No .NET Core SDKs were detected). 若要解决此问题,移动C:\Program Files\dotnet\到之前的位置C:\Program Files (x86)\dotnet\PATHTo resolve this problem, move C:\Program Files\dotnet\ to a position before C:\Program Files (x86)\dotnet\ on the PATH.

从应用中获取数据Obtain data from an app

如果应用程序能够对请求作出响应,你可以从应用使用中间件获取以下数据:If an app is capable of responding to requests, you can obtain the following data from the app using middleware:

  • 请求–方法、 方案、 主机、 pathbase、 路径、 查询字符串,标头Request – Method, scheme, host, pathbase, path, query string, headers
  • 连接–远程 IP 地址、 远程端口、 本地 IP 地址、 本地端口、 客户端证书Connection – Remote IP address, remote port, local IP address, local port, client certificate
  • 标识–名称、 显示名称Identity – Name, display name
  • 配置设置Configuration settings
  • 环境变量Environment variables

将以下项放中间件代码的开头Startup.Configure方法的请求处理管道。Place the following middleware code at the beginning of the Startup.Configure method's request processing pipeline. 中间件运行以确保仅在开发环境中执行的代码之前,将检查该环境。The environment is checked before the middleware is run to ensure that the code is only executed in the Development environment.

若要获取该环境,请使用以下方法之一:To obtain the environment, use either of the following approaches:

  • 注入IHostingEnvironmentStartup.Configure方法,并检查本地变量的环境。Inject the IHostingEnvironment into the Startup.Configure method and check the environment with the local variable. 下面的示例代码演示了这种方法。The following sample code demonstrates this approach.

  • 将在环境中的属性分配Startup类。Assign the environment to a property in the Startup class. 检查在环境中使用属性 (例如, if (Environment.IsDevelopment()))。Check the environment using the property (for example, if (Environment.IsDevelopment())).

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
    IConfiguration config)
{
    if (env.IsDevelopment())
    {
        app.Run(async (context) =>
        {
            var sb = new StringBuilder();
            var nl = System.Environment.NewLine;
            var rule = string.Concat(nl, new string('-', 40), nl);
            var authSchemeProvider = app.ApplicationServices
                .GetRequiredService<IAuthenticationSchemeProvider>();

            sb.Append($"Request{rule}");
            sb.Append($"{DateTimeOffset.Now}{nl}");
            sb.Append($"{context.Request.Method} {context.Request.Path}{nl}");
            sb.Append($"Scheme: {context.Request.Scheme}{nl}");
            sb.Append($"Host: {context.Request.Headers["Host"]}{nl}");
            sb.Append($"PathBase: {context.Request.PathBase.Value}{nl}");
            sb.Append($"Path: {context.Request.Path.Value}{nl}");
            sb.Append($"Query: {context.Request.QueryString.Value}{nl}{nl}");

            sb.Append($"Connection{rule}");
            sb.Append($"RemoteIp: {context.Connection.RemoteIpAddress}{nl}");
            sb.Append($"RemotePort: {context.Connection.RemotePort}{nl}");
            sb.Append($"LocalIp: {context.Connection.LocalIpAddress}{nl}");
            sb.Append($"LocalPort: {context.Connection.LocalPort}{nl}");
            sb.Append($"ClientCert: {context.Connection.ClientCertificate}{nl}{nl}");

            sb.Append($"Identity{rule}");
            sb.Append($"User: {context.User.Identity.Name}{nl}");
            var scheme = await authSchemeProvider
                .GetSchemeAsync(IISDefaults.AuthenticationScheme);
            sb.Append($"DisplayName: {scheme?.DisplayName}{nl}{nl}");

            sb.Append($"Headers{rule}");
            foreach (var header in context.Request.Headers)
            {
                sb.Append($"{header.Key}: {header.Value}{nl}");
            }
            sb.Append(nl);

            sb.Append($"Websockets{rule}");
            if (context.Features.Get<IHttpUpgradeFeature>() != null)
            {
                sb.Append($"Status: Enabled{nl}{nl}");
            }
            else
            {
                sb.Append($"Status: Disabled{nl}{nl}");
            }

            sb.Append($"Configuration{rule}");
            foreach (var pair in config.AsEnumerable())
            {
                sb.Append($"{pair.Path}: {pair.Value}{nl}");
            }
            sb.Append(nl);

            sb.Append($"Environment Variables{rule}");
            var vars = System.Environment.GetEnvironmentVariables();
            foreach (var key in vars.Keys.Cast<string>().OrderBy(key => key, 
                StringComparer.OrdinalIgnoreCase))
            {
                var value = vars[key];
                sb.Append($"{key}: {value}{nl}");
            }

            context.Response.ContentType = "text/plain";
            await context.Response.WriteAsync(sb.ToString());
        });
    }
}