为 Azure 应用服务配置 ASP.NET Core 应用

注意

对于 .NET Framework 中的 ASP.NET,请参阅为 Azure 应用服务配置 ASP.NET 应用。 如果 ASP.NET Core 应用在自定义 Windows 或 Linux 容器中运行,请参阅为 Azure 应用服务配置自定义容器

必须将 ASP.NET Core 应用作为编译的二进制文件部署到 Azure 应用服务。 Visual Studio 发布工具生成解决方案,然后直接部署编译的二进制文件。 应用服务部署引擎首先部署代码存储库,然后编译二进制文件。

本指南为 ASP.NET Core 开发者提供了重要概念和说明。 如果这是你第一次使用 Azure 应用服务,请首先按照 ASP.NET Core 快速入门ASP.NET Core 与 SQL 数据库教程

显示受支持的 .NET Core 运行时版本

在应用服务中,Windows 实例已安装了所有受支持的 .NET Core 版本。 若要查看可用的 .NET Core 运行时和 SDK 版本,请转到 https://<app-name>.scm.azurewebsites.net/DebugConsole 基于浏览器的控制台中运行以下命令:

dotnet --info

显示 .NET Core 版本

若要显示当前的 .NET Core 版本,请在 Azure Cloud Shell 中运行以下命令:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion

若要显示所有受支持的 .NET Core 版本,请在 Cloud Shell 中运行以下命令:

az webapp list-runtimes --os linux | grep DOTNET

设置 .NET Core 版本

在项目文件中为 ASP.NET Core 项目设置目标框架。 有关详细信息,请参阅 选择要使用的 .NET Core 版本

若要将 .NET Core 版本设置为 8.0,请在 Cloud Shell 中运行以下命令:

az webapp config set --name <app-name> --resource-group <resource-group-name> --linux-fx-version "DOTNETCORE|8.0"

自定义开发自动化

如果使用 启用了生成自动化的 Git 或 ZIP 包部署应用,应用服务生成自动化将遵循以下顺序:

  1. 运行 PRE_BUILD_SCRIPT_PATH 指定的自定义脚本。
  2. 若要还原 NuGet 依赖项,请运行 dotnet restore
  3. 若要生成用于生产的二进制文件,请运行 dotnet publish
  4. 运行 POST_BUILD_SCRIPT_PATH 指定的自定义脚本。

PRE_BUILD_COMMANDPOST_BUILD_COMMAND 是默认为空的环境变量。 若要运行生成前命令,请定义 PRE_BUILD_COMMAND。 若要运行生成后命令,请定义 POST_BUILD_COMMAND

以下示例在一系列命令中指定两个以逗号分隔的变量。

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings PRE_BUILD_COMMAND="echo foo, scripts/prebuild.sh"
az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings POST_BUILD_COMMAND="echo foo, scripts/postbuild.sh"

有关可用于自定义生成自动化的其他环境变量,请参阅 Oryx 配置

若要详细了解应用服务如何在 Linux 中运行和构建 ASP.NET Core 应用,请参阅 Oryx 文档:如何检测和构建 .NET Core 应用

访问环境变量

在应用服务中,可以在应用代码之外 设置应用设置 。 然后,可以使用标准 ASP.NET 核心依赖项注入模式在任何类中访问它们:

using Microsoft.Extensions.Configuration;

namespace SomeNamespace 
{
    public class SomeClass
    {
        private IConfiguration _configuration;
    
        public SomeClass(IConfiguration configuration)
        {
            _configuration = configuration;
        }
    
        public SomeMethod()
        {
            // retrieve nested App Service app setting
            var myHierarchicalConfig = _configuration["My:Hierarchical:Config:Data"];
            // retrieve App Service connection string
            var myConnString = _configuration.GetConnectionString("MyDbConnection");
        }
    }
}

如果在应用服务和 appsettings.json 中配置具有相同名称的应用设置,例如,应用服务的值优先于 appsettings.json 的值。 通过使用本地 appsettings.json 值,可以在本地调试应用,但通过使用应用服务值,可以使用生产设置在生产环境中运行应用。 连接字符串的使用方式与此相同。 通过使用此方法,可以在代码存储库之外保留应用程序机密并访问适当的值,而无需更改代码。

注意

还可以考虑更安全的连接选项,这些选项不需要连接机密。 有关详细信息,请参阅从 Azure应用服务安全地连接到 Azure 服务和数据库

appsettings.json 中的层次化配置数据是使用 Linux 上 .NET Core 的标准分隔符 __(双下划线)进行访问的。 若要替代应用服务中的特定层次化配置设置,请在密钥中设置具有相同分隔格式的应用设置名称。 可以在 Cloud Shell 中运行以下示例:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings My__Hierarchical__Config__Data="some value"

使用 .NET Core 标准的 : 分隔符访问 appsettings.json分层配置数据。 若要替代应用服务中的特定层次化配置设置,请在密钥中设置具有相同分隔格式的应用设置名称。 可以在 Azure Cloud Shell 中运行以下示例:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings My:Hierarchical:Config:Data="some value"

部署多项目解决方案

当 Visual Studio 解决方案包含多个项目时,Visual Studio 发布过程会自动选择要部署的项目。 部署到应用服务部署引擎(例如使用 Git 或 启用了生成自动化的 ZIP 部署)时,应用服务部署引擎会选取它作为应用服务应用找到的第一个网站或 Web 应用程序项目。 你可以通过指定 PROJECT 应用设置来指定应用服务应当使用哪个项目。 例如,在 Cloud Shell 中运行以下命令:

az webapp config appsettings set --resource-group <resource-group-name> --name <app-name> --settings PROJECT="<project-name>/<project-name>.csproj"

访问诊断日志

ASP.NET Core 提供了适用于应用服务的内置日志记录提供程序。 在项目的 program.cs 文件中,通过 ConfigureLogging 扩展方法将提供程序添加到应用程序,如以下示例所示:

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

然后,你可以使用标准 .NET Core 模式配置并生成日志。

若要访问应用服务中应用程序代码内部生成的控制台日志,请在 Cloud Shell 中运行以下命令来启用诊断日志记录:

az webapp log config --resource-group <resource-group-name> --name <app-name> --docker-container-logging filesystem --level Verbose

可能的值为 --levelErrorWarningInfoVerbose。 每个后续级别包括上一个级别。 例如, Error 仅包含错误消息。 Verbose 包括所有消息。

启用诊断日志记录后,运行以下命令以查看日志流:

az webapp log tail --resource-group <resource-group-name> --name <app-name>

如果未立即显示控制台日志,请在 30 秒内再次检查。

注意

也可通过浏览器在 https://<app-name>.scm.azurewebsites.net/api/logs/docker 中检查日志文件。 对于最近创建的应用,请使用 https://<app-name>-<random-hash>.scm.<region>.azurewebsites.net/

若要随时停止日志流式处理,请选择 Ctrl+C

有关在应用服务中排查 ASP.NET 核心应用问题的详细信息,请参阅 Azure 应用服务和 IIS 上的 ASP.NET Core 疑难解答

访问详细的异常页

当 ASP.NET Core 应用在 Visual Studio 调试器中生成异常时,浏览器会显示详细的异常页面,但在应用服务中,该页面将替换为泛型“HTTP 500”或“处理请求时出错”。若要在应用服务中显示详细的异常页,请在 Cloud Shell 中运行以下命令,将ASPNETCORE_ENVIRONMENT应用设置添加到应用。

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings ASPNETCORE_ENVIRONMENT="Development"

检测 HTTPS 会话

在应用服务中,TLS/SSL 终止在网络负载均衡器上发生,因此所有 HTTPS 请求将以未加密的 HTTP 请求形式访问你的应用。 如果应用逻辑需要知道用户请求是否已加密,请在以下项中 Startup.cs配置转发标头中间件:

  • 为中间件配置 ForwardedHeadersOptions 以转接 X-Forwarded-For 中的 X-Forwarded-ProtoStartup.ConfigureServices 标头。
  • 添加已知网络的专用 IP 地址范围,以便该中间件可以信任应用服务负载均衡器。
  • 在调用其他中间件之前,先调用UseForwardedHeaders方法中的Startup.Configure

组合这三个元素时,代码如以下示例所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        // These three subnets encapsulate the applicable Azure subnets. At the moment, it's not possible to narrow it down further.
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:10.0.0.0"), 104));
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:192.168.0.0"), 112));
        options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("::ffff:172.16.0.0"), 108));
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseForwardedHeaders();

    ...

    app.UseMvc();
}

有关详细信息,请参阅配置 ASP.NET Core 以使用代理服务器和负载均衡器

重写或重定向 URL

若要重写或重定向 URL,请使用 ASP.NET Core 中的 URL 重写中间件

在浏览器中打开 SSH 会话

若要打开与容器的直接 SSH 会话,应用应正在运行。

将以下 URL 粘贴到浏览器中,并将应用名称>替换为<应用名称:

https://<app-name>.scm.azurewebsites.net/webssh/host

如果尚未进行身份验证,则需通过要连接的 Azure 订阅进行身份验证。 完成身份验证以后,可以看到一个浏览器内 shell,可以在其中的容器中运行命令。

SSH 连接

注意

在目录外部 /home 所做的任何更改都存储在容器本身中,并且不会在应用重启之后保留。

若要从本地计算机打开远程 SSH 会话,请参阅从远程 shell 打开 SSH 会话

忽略日志中的 robots933456 消息

容器日志中可能会显示以下消息:

2019-04-08T14:07:56.641002476Z "-" - - [08/Apr/2019:14:07:56 +0000] "GET /robots933456.txt HTTP/1.1" 404 415 "-" "-"

可以放心忽略此消息。 /robots933456.txt 是一个虚拟 URL 路径,应用服务使用它来检查容器能否为请求提供服务。 404 响应指示路径不存在,它向应用服务发出信号,表明容器正常运行并已准备好响应请求。