ASP.NET Core 中的應用程式啟動

Kirk LarkinRick Anderson

使用 web 範本建立的 ASP.NET Core 應用程式會在檔案中 Program.cs 包含應用程式啟動程式碼。

下列應用程式啟動程式碼支援:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthorization();

app.MapGet("/hi", () => "Hello!");

app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

如需應用程式啟動的詳細資訊,請參閱ASP.NET Core 基礎總覽

Startup 類別可設定服務和應用程式的要求管線。

Startup 類別

ASP.NET Core 應用程式使用 Startup 類別,其依慣例命名為 StartupStartup 類別:

  • 選擇性地包含 ConfigureServices 方法來設定應用程式的服務。 服務的定義是可提供應用程式功能的可重複使用元件。 服務會透過相依性插入 (DI) ApplicationServices ,在整個應用程式中 ConfigureServices註冊及取用。
  • 包含 Configure 方法來建立應用程式的要求處理管線。

應用程式啟動時,ASP.NET Core 執行階段會呼叫 ConfigureServicesConfigure

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

上述範例適用于Razor 頁面; MVC 版本很類似。

一旦建置應用程式主機,就會指定 Startup 類別。 Startup 類別通常會藉由呼叫主機產生器上的 WebHostBuilderExtensions.UseStartup/<TStartup> 方法來指定:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

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

主機會提供可供 Startup 類別建構函式使用的服務。 應用程式會透過 ConfigureServices 新增其他服務。 主機和應用程式服務都可以在 Configure 和整個應用程式中使用。

使用泛型主機 (IHostBuilder) 時,只可將下列服務類型插入至 Startup 函式:

public class Startup
{
    private readonly IWebHostEnvironment _env;

    public Startup(IConfiguration configuration, IWebHostEnvironment env)
    {
        Configuration = configuration;
        _env = env;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        if (_env.IsDevelopment())
        {
        }
        else
        {
        }
    }
}

在呼叫 Configure 方法之前,大部分的服務都無法使用。

多重啟動

應用程式針對不同的環境定義個別的 Startup 類別 (例如 StartupDevelopment) 時,會在執行階段選取適當的 Startup 類別。 將優先使用其名稱尾碼符合目前環境的類別。 如果應用程式是在開發環境中執行,且同時包含 Startup 類別和 StartupDevelopment 類別,則會使用 StartupDevelopment 類別。 如需詳細資訊,請參閱使用多重環境

如需主機的詳細資訊,請參閱主機。 如需在啟動期間處理錯誤的資訊,請參閱啟動例外狀況處理

ConfigureServices 方法

ConfigureServices 方法為:

  • 選擇性。
  • 由主機在 Configure 方法之前呼叫,來設定應用程式的服務。
  • 組態選項依慣例設定的位置。

主機可能會在呼叫 Startup 方法之前,設定一些服務。 如需詳細資訊,請參閱主機

對於需要大量安裝的功能,可從 IServiceCollection 上取得 Add{Service} 擴充方法。 例如,新增DbCoNtext、新增預設值 Identity 、新增EntityFrameworkStores,以及新增Razor 頁面:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
            options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddRazorPages();
    }

將服務新增至服務容器,使其可在應用程式和 Configure 方法內使用。 服務可透過相依性插入或從 ApplicationServices 獲得解析。

Configure 方法

Configure 方法可用來指定應用程式對 HTTP 要求的回應方式。 藉由將中介軟體元件新增至 IApplicationBuilder 執行個體,即可設定要求管線。 IApplicationBuilder 可用於 Configure 方法,但它未註冊在服務容器中。 裝載會建立 IApplicationBuilder,並將它直接傳遞到 Configure

ASP.NET Core 範本會以下列支援設定管線:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

上述範例適用于Razor 頁面; MVC 版本很類似。

Use 擴充方法會將一或多個中介軟體元件新增到要求管線。 例如,UseStaticFiles 會設定中介軟體來提供靜態檔案

要求管線中的每個中介軟體元件負責叫用管線中的下一個元件,或於適當時,對鏈結執行最少運算。

IWebHostEnvironmentILoggerFactory 或任何在 ConfigureServices 中定義的其他服務,也可以在 Configure 方法簽章中指定。 這些服務在可用時即會插入。

如需如何使用 IApplicationBuilder 和中介軟體處理順序的詳細資訊,請參閱ASP.NET Core 中介軟體

在不啟動的情況下設定服務

若要設定服務及要求處理管線,且不使用 Startup 類別,請在主機建立器上呼叫 ConfigureServicesConfigure 便利方法。 多次呼叫 ConfigureServices 會彼此附加。 若多個 Configure 方法呼叫存在,則會使用最後的 Configure 呼叫。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.ConfigureServices(services =>
                {
                    services.AddControllersWithViews();
                })
                .Configure(app =>
                {
                    var loggerFactory = app.ApplicationServices
                        .GetRequiredService<ILoggerFactory>();
                    var logger = loggerFactory.CreateLogger<Program>();
                    var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
                    var config = app.ApplicationServices.GetRequiredService<IConfiguration>();

                    logger.LogInformation("Logged in Configure");

                    if (env.IsDevelopment())
                    {
                        app.UseDeveloperExceptionPage();
                    }
                    else
                    {
                        app.UseExceptionHandler("/Home/Error");
                        app.UseHsts();
                    }

                    var configValue = config["MyConfigKey"];
                });
            });
        });
}

使用啟動篩選條件來擴充啟動

使用 IStartupFilter

  • 在應用程式 設定 中介軟體管線的開頭或結尾設定中介軟體,而不需要明確呼叫 Use{Middleware}IStartupFilterASP.NET Core 用來將預設值新增至管線的開頭,而不需要讓應用程式作者明確地註冊預設中介軟體。 IStartupFilter 允許代表應用程式作者呼叫 Use{Middleware} 不同的元件。
  • 建立方法的 Configure 管線。 IStartupFilter.Configure 可以將中介軟體設為在程式庫新增中介軟體之前或之後執行。

IStartupFilter 會實作 Configure,其會接收並傳回 Action<IApplicationBuilder>IApplicationBuilder 會定義類別,以設定應用程式的要求管線。 如需詳細資訊,請參閱使用 IApplicationBuilder 建立中介軟體管線

每個 IStartupFilter 都可在要求管線中新增一或多個中介軟體。 篩選條件將依照它們新增至服務容器的順序叫用。 篩選條件可能會在控制權傳給下一個篩選條件之前或之後新增中介軟體,因此它們會附加至應用程式管線的開頭或結尾。

以下範例示範如何使用 IStartupFilter 註冊中介軟體。 此 RequestSetOptionsMiddleware 中介軟體會從查詢字串參數設定選項值:

public class RequestSetOptionsMiddleware
{
    private readonly RequestDelegate _next;

    public RequestSetOptionsMiddleware( RequestDelegate next )
    {
        _next = next;
    }

    // Test with https://localhost:5001/Privacy/?option=Hello
    public async Task Invoke(HttpContext httpContext)
    {
        var option = httpContext.Request.Query["option"];

        if (!string.IsNullOrWhiteSpace(option))
        {
            httpContext.Items["option"] = WebUtility.HtmlEncode(option);
        }

        await _next(httpContext);
    }
}

RequestSetOptionsMiddleware 設定在 RequestSetOptionsStartupFilter 類別中:

public class RequestSetOptionsStartupFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        return builder =>
        {
            builder.UseMiddleware<RequestSetOptionsMiddleware>();
            next(builder);
        };
    }
}

IStartupFilter 註冊在 ConfigureServices 的服務容器中。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
           .ConfigureAppConfiguration((hostingContext, config) =>
           {
           })
         .ConfigureWebHostDefaults(webBuilder =>
         {
             webBuilder.UseStartup<Startup>();
         })
        .ConfigureServices(services =>
        {
            services.AddTransient<IStartupFilter,
                      RequestSetOptionsStartupFilter>();
        });
}

提供 option 的查詢字串參數時,中介軟體會在 ASP.NET Core 中介軟體轉譯回應之前,先處理值指派。

中介軟體執行順序是依照 IStartupFilter 註冊順序來設定:

  • 多個 IStartupFilter 實作可能會與相同的物件互動。 如果順序很重要,請排列其 IStartupFilter 服務註冊順序,以符合其中介軟體執行應該依照的順序。

  • 程式庫可能使用一或多個 IStartupFilter 實作 (其在使用 IStartupFilter 註冊的其他應用程式中介軟體之前或之後執行) 來新增中介軟體。 在由程式庫的 IStartupFilter 所新增中介軟體之前叫用 IStartupFilter 中介軟體:

    • 先放置服務註冊,再將程式庫新增至服務容器。
    • 若要在之後叫用,請在新增程式庫之後放置服務註冊。

在啟動時從外部組件新增組態

IHostingStartup 實作允許在啟動時從應用程式 Startup 類別外部的外部組件,針對應用程式新增增強功能。 如需詳細資訊,請參閱在 ASP.NET Core 中使用裝載啟動元件

其他資源