为 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.chinacloudsites.cn/DebugConsole 并在基于浏览器的控制台中运行以下命令:

dotnet --info

显示 .NET Core 版本

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

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

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

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

设置 .NET Core 版本

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

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

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. 运行 dotnet restore 来还原 NuGet 依赖项。
  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 Core 依赖项注入模式在任何类中访问它们:

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 的标准分隔符 __(双下划线)进行访问的。 若要替代应用服务中的特定层次化配置设置,请在密钥中设置具有相同分隔格式的应用设置名称。 你可以在 Azure CLI 中运行以下示例:

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

注意

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

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 应用设置来指定应用服务应当使用哪个项目。 例如,在 Azure CLI 中运行以下命令:

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 模式配置并生成日志。

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

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

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

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

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

如果没有立即看到控制台日志,请在 30 秒后重新查看。

注意

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。

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

若要详细了解如何对应用服务中的 ASP.NET Core 应用进行故障排除,请参阅对 Azure 应用服务和 IIS 上的 ASP.NET Core 进行故障排除

获取详细的异常页面

当 ASP.NET Core 应用在 Visual Studio 调试器中生成异常时,浏览器会显示一个详细的异常页面,但在应用服务中,该页面被替换为通用 HTTP 500处理请求时发生的某个错误。若要在应用服务中显示详细的异常页面,请在 Azure CLI 中运行以下命令,将 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 中配置 Forwarded Headers 中间件:

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

将所有这三个元素放在一起,代码类似于以下示例:

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 粘贴到浏览器中,将 <app-name> 替换为应用名称:

https://<app-name>.scm.chinacloudsites.cn/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 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。

后续步骤

或查看更多资源:

环境变量和应用设置参考