为 Azure 应用服务配置 ASP.NET Core 应用Configure an ASP.NET Core app for Azure App Service

备注

对于 .NET Framework 中的 ASP.NET,请参阅为 Azure 应用服务配置 ASP.NET 应用For ASP.NET in .NET Framework, see Configure an ASP.NET app for Azure App Service

必须将 ASP.NET Core 应用作为编译的二进制文件部署到 Azure 应用服务。ASP.NET Core apps must be deployed to Azure App Service as compiled binaries. Visual Studio 发布工具先构建解决方案,然后直接部署已编译的二进制文件,而应用服务部署引擎则先部署代码存储库,然后编译二进制文件。The Visual Studio publishing tool builds the solution and then deploys the compiled binaries directly, whereas the App Service deployment engine deploys the code repository first and then compiles the binaries.

本指南为 ASP.NET Core 开发者提供了重要概念和说明。This guide provides key concepts and instructions for ASP.NET Core developers. 如果你从未使用过 Azure 应用服务,则应首先按照 ASP.NET Core 快速入门将 ASP.NET Core 与 SQL 数据库配合使用教程进行操作。If you've never used Azure App Service, follow the ASP.NET Core quickstart and ASP.NET Core with SQL Database tutorial first.

显示受支持的 .NET Core 运行时版本Show supported .NET Core runtime versions

在应用服务中,Windows 实例已安装了所有受支持的 .NET Core 版本。In App Service, the Windows instances already have all the supported .NET Core versions installed. 若要显示可供使用的 .NET Core 运行时和 SDK 版本,请导航到 https://<app-name>.scm.chinacloudsites.cn/DebugConsole 并在基于浏览器的控制台中运行以下命令:To show the .NET Core runtime and SDK versions available to you, navigate to https://<app-name>.scm.chinacloudsites.cn/DebugConsole and run the following command in the browser-based console:

dotnet --info

显示 .NET Core 版本Show .NET Core version

若要显示当前的 .NET Core 版本,请在 Azure CLI 中运行以下命令:To show the current .NET Core version, run the following command in the Azure CLI:

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

若要显示所有受支持的 .NET Core 版本,请在 Azure CLI 中运行以下命令:To show all supported .NET Core versions, run the following command in the Azure CLI:

az webapp list-runtimes --linux | grep DOTNETCORE

设置 .NET Core 版本Set .NET Core version

在项目文件中为 ASP.NET Core 项目设置目标框架。Set the target framework in the project file for your ASP.NET Core project. 有关详细信息,请参阅 .NET Core 文档中的选择要使用 的 .NET Core 版本For more information, see Select the .NET Core version to use in .NET Core documentation.

若要将 .NET Core 版本设置为 3.1,请在 Azure CLI 中运行以下命令:Run the following command in the Azure CLI to set the .NET Core version to 3.1:

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

自定义生成自动化Customize build automation

如果在启用生成自动化的情况下使用 Git 或 zip 包部署应用,应用服务生成自动化将按以下顺序完成各个步骤:If you deploy your app using Git or zip packages with build automation turned on, the App Service build automation steps through the following sequence:

  1. 运行 PRE_BUILD_SCRIPT_PATH 指定的自定义脚本。Run custom script if specified by PRE_BUILD_SCRIPT_PATH.
  2. 运行 dotnet restore 来还原 NuGet 依赖项。Run dotnet restore to restore NuGet dependencies.
  3. 运行 dotnet publish 来构建用于生产的二进制文件。Run dotnet publish to build a binary for production.
  4. 运行 POST_BUILD_SCRIPT_PATH 指定的自定义脚本。Run custom script if specified by POST_BUILD_SCRIPT_PATH.

PRE_BUILD_COMMANDPOST_BUILD_COMMAND 是默认为空的环境变量。PRE_BUILD_COMMAND and POST_BUILD_COMMAND are environment variables that are empty by default. 若要运行生成前命令,请定义 PRE_BUILD_COMMANDTo run pre-build commands, define PRE_BUILD_COMMAND. 若要运行生成后命令,请定义 POST_BUILD_COMMANDTo run post-build commands, define POST_BUILD_COMMAND.

以下示例在一系列命令中指定两个以逗号分隔的变量。The following example specifies the two variables to a series of commands, separated by commas.

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 配置For additional environment variables to customize build automation, see Oryx configuration.

若要详细了解应用服务如何在 Linux 中运行和构建 ASP.NET Core 应用,请参阅 Oryx 文档:如何检测和构建 .NET Core 应用For more information on how App Service runs and builds ASP.NET Core apps in Linux, see Oryx documentation: How .NET Core apps are detected and built.

访问环境变量Access environment variables

在应用服务中,可以在应用代码外部设置应用设置In App Service, you can set app settings outside of your app code. 然后,你可以使用标准 ASP.NET Core 依赖项注入模式在任何类中访问它们:Then you can access them in any class using the standard ASP.NET Core dependency injection pattern:

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 值。If you configure an app setting with the same name in App Service and in appsettings.json, for example, the App Service value takes precedence over the appsettings.json value. 本地 appsettings.json 值允许你在本地调试应用,但应用服务值允许你使用生产设置在生产中运行应用。The local appsettings.json value lets you debug the app locally, but the App Service value lets your run the app in product with production settings. 连接字符串的使用方式与此相同。Connection strings work in the same way. 这样,你可以将应用程序机密保存在代码存储库外部,无需更改代码便可访问相应的值。This way, you can keep your application secrets outside of your code repository and access the appropriate values without changing your code.

备注

请注意,appsettings.json 中的层次化配置数据是使用 .NET Core 的标准分隔符 : 进行访问的。Note the hierarchical configuration data in appsettings.json is accessed using the : delimiter that's standard to .NET Core. 若要替代应用服务中的特定层次化配置设置,请在密钥中设置具有相同分隔格式的应用设置名称。To override a specific hierarchical configuration setting in App Service, set the app setting name with the same delimited format in the key. 你可以在 Azure CLI 中运行以下示例:you can run the following example in the Azure CLI:

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

部署多项目解决方案Deploy multi-project solutions

如果 Visual Studio 解决方案包含多个项目,则说明 Visual Studio 发布过程已包括选择要部署的项目的操作。When a Visual Studio solution includes multiple projects, the Visual Studio publish process already includes selecting the project to deploy. 当你部署到应用服务部署引擎(例如,使用 Git 或 ZIP 部署)时,如果启用了“生成自动化”,则应用服务部署引擎会选取它发现的第一个网站或 Web 应用程序项目作为应用服务应用。When you deploy to the App Service deployment engine, such as with Git or with ZIP deploy, with build automation turned on, the App Service deployment engine picks the first Web Site or Web Application Project it finds as the App Service app. 你可以通过指定 PROJECT 应用设置来指定应用服务应当使用哪个项目。You can specify which project App Service should use by specifying the PROJECT app setting. 例如,在 Azure CLI 中运行以下命令:For example, run the following in the Azure CLI:

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

访问诊断日志Access diagnostic logs

ASP.NET Core 提供了适用于应用服务的内置日志记录提供程序ASP.NET Core provides a built-in logging provider for App Service. 在项目的 Program.cs 中,通过 ConfigureLogging 扩展方法将该提供程序添加到应用程序,如以下示例所示:In Program.cs of your project, add the provider to your application through the ConfigureLogging extension method, as shown in the following example:

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

然后,你可以使用标准 .NET Core 模式配置并生成日志。You can then configure and generate logs with the standard .NET Core pattern.

若要访问应用服务中的应用程序代码内生成的控制台日志,请在 Azure CLI 中运行以下命令以打开诊断日志记录:To access the console logs generated from inside your application code in App Service, turn on diagnostics logging by running the following command in the Azure CLI:

az webapp log config --resource-group <resource-group-name> --name <app-name> --application-logging true --level Verbose

--level 的可能值为:ErrorWarningInfoVerbosePossible values for --level are: Error, Warning, Info, and Verbose. 每个后续级别包括上一个级别。Each subsequent level includes the previous level. 例如:Error 仅包含错误消息,Verbose 则包含所有消息。For example: Error includes only error messages, and Verbose includes all messages.

启用诊断日志记录功能以后,请运行以下命令来查看日志流:Once diagnostic logging is turned on, run the following command to see the log stream:

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

如果没有立即看到控制台日志,请在 30 秒后重新查看。If you don't see console logs immediately, check again in 30 seconds.

备注

也可通过浏览器在 https://<app-name>.scm.chinacloudsites.cn/api/logs/docker 中检查日志文件。You can also inspect the log files from the browser at https://<app-name>.scm.chinacloudsites.cn/api/logs/docker.

若要随时停止日志流式处理,请键入 Ctrl+CTo stop log streaming at any time, type Ctrl+C.

若要详细了解如何对应用服务中的 ASP.NET Core 应用进行故障排除,请参阅对 Azure 应用服务和 IIS 上的 ASP.NET Core 进行故障排除For more information on troubleshooting ASP.NET Core apps in App Service, see Troubleshoot ASP.NET Core on Azure App Service and IIS

获取详细的异常页面Get detailed exceptions page

当 ASP.NET Core 应用在 Visual Studio 调试器中生成异常时,浏览器会显示一个详细的异常页面,但在应用服务中,该页面被替换为一般 HTTP 500 错误或处理请求时发生的某个错误When your ASP.NET Core app generates an exception in the Visual Studio debugger, the browser displays a detailed exception page, but in App Service that page is replaced by a generic HTTP 500 error or An error occurred while processing your request. message. 若要在应用服务中显示详细的异常页面,请在 Azure CLI 中运行以下命令,将 ASPNETCORE_ENVIRONMENT 应用设置添加到应用。To display the detailed exception page in App Service, Add the ASPNETCORE_ENVIRONMENT app setting to your app by running the following command in the Azure CLI.

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

检测 HTTPS 会话Detect HTTPS session

在应用服务中,SSL 终止在网络负载均衡器上发生,因此,所有 HTTPS 请求将以未加密的 HTTP 请求形式访问你的应用。In App Service, SSL termination happens at the network load balancers, so all HTTPS requests reach your app as unencrypted HTTP requests. 如果你的应用逻辑需要知道用户请求是否已加密,请在 Startup.cs 中配置 Forwarded Headers 中间件:If your app logic needs to know if the user requests are encrypted or not, configure the Forwarded Headers Middleware in Startup.cs:

  • 使用 ForwardedHeadersOptions 配置中间件,以转接 Startup.ConfigureServices 中的 X-Forwarded-ForX-Forwarded-Proto 标头。Configure the middleware with ForwardedHeadersOptions to forward the X-Forwarded-For and X-Forwarded-Proto headers in Startup.ConfigureServices.
  • 添加已知网络的专用 IP 地址范围,以便该中间件可以信任应用服务负载均衡器。Add private IP address ranges to the known networks, so that the middleware can trust the App Service load balancer.
  • 在调用其他中间件之前在 Startup.Configure 中调用 UseForwardedHeaders 方法。Invoke the UseForwardedHeaders method in Startup.Configure before calling other middleware.

将所有这三个元素放在一起,代码类似于以下示例:Putting all three elements together, your code looks like the following example:

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

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        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 以使用代理服务器和负载均衡器For more information, see Configure ASP.NET Core to work with proxy servers and load balancers.

在浏览器中打开 SSH 会话Open SSH session in browser

若要通过容器打开直接的 SSH 会话,应用应该处于正在运行状态。To make open a direct SSH session with your container, your app should be running.

将以下 URL 粘贴到浏览器中,将 <app-name> 替换为应用名称:Paste the following URL into your browser and replace <app-name> with your app name:

https://<app-name>.scm.chinacloudsites.cn/webssh/host

如果尚未进行身份验证,则需通过要连接的 Azure 订阅进行身份验证。If you're not yet authenticated, you're required to authenticate with your Azure subscription to connect. 完成身份验证以后,可以看到一个浏览器内 shell,可以在其中的容器中运行命令。Once authenticated, you see an in-browser shell, where you can run commands inside your container.

SSH 连接

备注

/home 目录之外进行的任何更改均存储在容器本身中,在应用重启后不保留。Any changes you make outside the /home directory are stored in the container itself and don't persist beyond an app restart.

若要从本地计算机打开远程 SSH 会话,请参阅从远程 shell 打开 SSH 会话To open a remote SSH session from your local machine, see Open SSH session from remote shell.

日志中的 robots933456robots933456 in logs

你可能会在容器日志中看到以下消息:You may see the following message in the container logs:

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

可以放心忽略此消息。You can safely ignore this message. /robots933456.txt 是一个虚拟 URL 路径,应用服务使用它来检查容器能否为请求提供服务。/robots933456.txt is a dummy URL path that App Service uses to check if the container is capable of serving requests. 404 响应只是指示该路径不存在,但它让应用服务知道容器处于正常状态并已准备就绪,可以响应请求。A 404 response simply indicates that the path doesn't exist, but it lets App Service know that the container is healthy and ready to respond to requests.

后续步骤Next steps