Inicio de la aplicación en ASP.NET Core
Nota
Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulta la versión .NET 8 de este artículo.
Por Rick Anderson
Las aplicaciones de ASP.NET Core creadas con las plantillas web contienen el código de inicio de la aplicación en el archivo Program.cs
.
Para obtener una guía sobre el inicio de Blazor, que se agregue o reemplace la guía en este nodo, consulta Inicio de Blazor en ASP.NET Core.
El siguiente código de inicio de la aplicación admite:
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();
Las aplicaciones que usan EventSource pueden medir el tiempo de inicio para comprender y optimizar el rendimiento de inicio. El evento ServerReady
de Microsoft.AspNetCore.Hosting representa el punto en el que el servidor está listo para responder a las solicitudes.
Para obtener más información sobre el inicio de la aplicación, consulte Información general de los conceptos básicos de ASP.NET Core.
Extensión del inicio con filtros de inicio
Use IStartupFilter:
- Para configurar el middleware al principio o al final de la canalización de middleware de una aplicación sin una llamada explícita a
Use{Middleware}
. UseIStartupFilter
para agregar valores predeterminados al principio de la canalización sin registrar explícitamente el middleware predeterminado.IStartupFilter
permite que otro componente llame aUse{Middleware}
en nombre del creador de la aplicación. - Para crear una canalización de métodos
Configure
. IStartupFilter.Configure puede configurar middleware para que se ejecute antes o después del middleware agregado por las bibliotecas.
IStartupFilter
implementa Configure, que recibe y devuelve un elemento Action<IApplicationBuilder>
. IApplicationBuilder define una clase para configurar la canalización de solicitudes de una aplicación. Para más información, vea Creación de una canalización de middleware con IApplicationBuilder.
Cada instancia de IStartupFilter
puede agregar uno o más middleware en la canalización de solicitudes. Los filtros se invocan en el orden en que se agregaron al contenedor de servicios. Los filtros pueden agregar middleware antes o después de pasar el control al siguiente filtro, por lo que se anexan al principio o al final de la canalización de la aplicación.
En el ejemplo siguiente, se muestra cómo registrar un componente de middleware con IStartupFilter
. El componente de middleware RequestSetOptionsMiddleware
establece un valor de opciones de un parámetro de cadena de consulta:
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
está configurado en las clase RequestSetOptionsStartupFilter
:
namespace WebStartup.Middleware;
// <snippet1>
public class RequestSetOptionsStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestSetOptionsMiddleware>();
next(builder);
};
}
}
// </snippet1>
IStartupFilter
está registrado en Program.cs
:
using WebStartup.Middleware;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddTransient<IStartupFilter,
RequestSetOptionsStartupFilter>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Cuando se proporciona un parámetro de cadena de consulta para option
, el middleware procesa la asignación del valor antes de que el middleware de ASP.NET Core represente la respuesta:
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p> Append query string ?option=hello</p>
Option String: @HttpContext.Items["option"];
El orden de ejecución de middleware se establece según el orden de registros de IStartupFilter
:
Varias implementaciones de
IStartupFilter
pueden interactuar con los mismos objetos. Si el orden es importante, ordene los registros de servicio deIStartupFilter
para que coincidan con el orden en que se deben ejecutar los middleware.Las bibliotecas pueden agregar middleware con una o varias implementaciones de
IStartupFilter
que se ejecuten antes o después de otro middleware de aplicación registrado conIStartupFilter
. Para invocar un middlewareIStartupFilter
antes de un middleware agregado por el elementoIStartupFilter
de una biblioteca:- Coloque el registro del servicio antes de que la biblioteca se agregue al contenedor de servicios.
- Para la invocación posterior, coloque el registro del servicio después de que se agregue la biblioteca.
Nota: No se puede extender la aplicación de ASP.NET Core al invalidar Configure
. Para obtener más información, vea esta incidencia de GitHub.
Agregar opciones de configuración en el inicio desde un ensamblado externo
Una implementación de IHostingStartup permite agregar mejoras a una aplicación al iniciarla a partir de un ensamblado externo fuera del archivoProgram.cs
de esta. Para obtener más información, consulte Uso de ensamblados de inicio de hospedaje en ASP.NET Core.
Startup, ConfigureServices y Configure
Para información sobre el uso de los métodos ConfigureServices y Configure con el modelo de hospedaje mínimo, consulte:
Las aplicaciones de ASP.NET Core creadas con las plantillas web contienen el código de inicio de la aplicación en el archivo Program.cs
.
El siguiente código de inicio de la aplicación admite:
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();
Para obtener más información sobre el inicio de la aplicación, consulte Información general de los conceptos básicos de ASP.NET Core.
Extensión del inicio con filtros de inicio
Use IStartupFilter:
- Para configurar el middleware al principio o al final de la canalización de middleware de una aplicación sin una llamada explícita a
Use{Middleware}
. UseIStartupFilter
para agregar valores predeterminados al principio de la canalización sin registrar explícitamente el middleware predeterminado.IStartupFilter
permite que otro componente llame aUse{Middleware}
en nombre del creador de la aplicación. - Para crear una canalización de métodos
Configure
. IStartupFilter.Configure puede configurar middleware para que se ejecute antes o después del middleware agregado por las bibliotecas.
IStartupFilter
implementa Configure, que recibe y devuelve un elemento Action<IApplicationBuilder>
. IApplicationBuilder define una clase para configurar la canalización de solicitudes de una aplicación. Para más información, vea Creación de una canalización de middleware con IApplicationBuilder.
Cada instancia de IStartupFilter
puede agregar uno o más middleware en la canalización de solicitudes. Los filtros se invocan en el orden en que se agregaron al contenedor de servicios. Los filtros pueden agregar middleware antes o después de pasar el control al siguiente filtro, por lo que se anexan al principio o al final de la canalización de la aplicación.
En el ejemplo siguiente, se muestra cómo registrar un componente de middleware con IStartupFilter
. El componente de middleware RequestSetOptionsMiddleware
establece un valor de opciones de un parámetro de cadena de consulta:
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
está configurado en las clase RequestSetOptionsStartupFilter
:
namespace WebStartup.Middleware;
// <snippet1>
public class RequestSetOptionsStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestSetOptionsMiddleware>();
next(builder);
};
}
}
// </snippet1>
IStartupFilter
está registrado en Program.cs
:
using WebStartup.Middleware;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddTransient<IStartupFilter,
RequestSetOptionsStartupFilter>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Cuando se proporciona un parámetro de cadena de consulta para option
, el middleware procesa la asignación del valor antes de que el middleware de ASP.NET Core represente la respuesta:
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p> Append query string ?option=hello</p>
Option String: @HttpContext.Items["option"];
El orden de ejecución de middleware se establece según el orden de registros de IStartupFilter
:
Varias implementaciones de
IStartupFilter
pueden interactuar con los mismos objetos. Si el orden es importante, ordene los registros de servicio deIStartupFilter
para que coincidan con el orden en que se deben ejecutar los middleware.Las bibliotecas pueden agregar middleware con una o varias implementaciones de
IStartupFilter
que se ejecuten antes o después de otro middleware de aplicación registrado conIStartupFilter
. Para invocar un middlewareIStartupFilter
antes de un middleware agregado por el elementoIStartupFilter
de una biblioteca:- Coloque el registro del servicio antes de que la biblioteca se agregue al contenedor de servicios.
- Para la invocación posterior, coloque el registro del servicio después de que se agregue la biblioteca.
Nota: No se puede extender la aplicación de ASP.NET Core al invalidar Configure
. Para más información, consulte este problema de GitHub.
Agregar opciones de configuración en el inicio desde un ensamblado externo
Una implementación de IHostingStartup permite agregar mejoras a una aplicación al iniciarla a partir de un ensamblado externo fuera del archivoProgram.cs
de esta. Para obtener más información, consulte Uso de ensamblados de inicio de hospedaje en ASP.NET Core.
La clase Startup
configura los servicios y la canalización de solicitudes de la aplicación.
Clase Startup
Las aplicaciones de ASP.NET Core utilizan una clase Startup
, que se denomina Startup
por convención. La clase Startup
:
- Incluye opcionalmente un método ConfigureServices para configurar los ConfigureServices de la aplicación. Un servicio es un componente reutilizable que proporciona funcionalidades de la aplicación. Los servicios se registran en
ConfigureServices
y se usan en la aplicación a través de la inserción de dependencias (DI) o ApplicationServices. - Incluye un método Configure para crear la canalización de procesamiento de solicitudes de la aplicación.
El tiempo de ejecución ASP.NET Core llama a ConfigureServices
y Configure
cuando la aplicación se inicia:
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();
});
}
}
El ejemplo anterior corresponde a Razor Pages; la versión para MVC es similar.
La clase Startup
se especifica cuando se crea el Startup
de la aplicación. Normalmente, la clase Startup
se especifica mediante la llamada al método WebHostBuilderExtensions.UseStartup
/<TStartup>
en el generador de host:
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>();
});
}
El host proporciona servicios que están disponibles para el constructor de clase Startup
. La aplicación agrega servicios adicionales a través de ConfigureServices
. Los servicios de la aplicación y el host están disponibles en Configure
y en toda la aplicación.
Solo se pueden insertar los tipos de servicio siguientes en el constructor Startup
cuando se usa el Startup
(IHostBuilder):
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
{
}
}
}
La mayoría de los servicios no están disponibles hasta que se llama al método Configure
.
Inicio múltiple
Cuando la aplicación define clases Startup
independientes para otros entornos (por ejemplo, StartupDevelopment
), la clase Startup
correspondiente se selecciona en tiempo de ejecución. La clase cuyo sufijo de nombre coincide con el entorno actual se establece como prioritaria. Si la aplicación se ejecuta en el entorno de desarrollo e incluye tanto la clase Startup
como la clase StartupDevelopment
, se utiliza la clase StartupDevelopment
. Para obtener más información, consulte Uso de varios entornos.
Para obtener más información sobre el host, vea El host. Para obtener información sobre cómo controlar los errores que se producen durante el inicio, consulte Control de excepciones de inicio.
Método ConfigureServices
El método ConfigureServices es:
- Opcional.
- Lo llama el host antes del método
Configure
para configurar los servicios de la aplicación. - Es donde se establecen por convención las opciones de configuración.
El host puede configurar algunos servicios antes de que se llame a los métodos Startup
. Para obtener más información, vea El host.
Para las características que requieren una configuración sustancial, hay métodos de extensión Add{Service}
en IServiceCollection. Por ejemplo, AddDbContext, AddDefaultIdentity, AddEntityFrameworkStores y AddRazorPages:
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();
}
La adición de servicios al contenedor de servicios hace que estén disponibles en la aplicación y en el método Configure
. Los servicios se resuelven a través de la inserción de dependencias o desde ApplicationServices.
El método Configure
El método Configure se usa para especificar la forma en que la aplicación responde a las solicitudes HTTP. La canalización de solicitudes se configura mediante la adición de componentes de middleware a una instancia de IApplicationBuilder. IApplicationBuilder
está disponible para el método Configure
, pero no está registrado en el contenedor de servicios. El hospedaje crea un elemento IApplicationBuilder
y lo pasa directamente a Configure
.
Las plantillas de ASP.NET Core configuran la canalización con compatibilidad para lo siguiente:
- Página de excepciones para el desarrollador
- Controlador de excepciones
- Seguridad de transporte estricta de HTTP (HSTS)
- Redireccionamiento de HTTPS
- Archivos estáticos
- ASP.NET Core MVC y Razor Pages
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();
});
}
}
El ejemplo anterior corresponde a Razor Pages; la versión para MVC es similar.
Cada método de extensión Use
agrega uno o más componentes de middleware a la canalización de solicitudes. Por ejemplo, UseStaticFiles configura UseStaticFiles para proporcionar archivos estáticos.
Cada componente de middleware de la canalización de solicitudes es responsable de invocar al siguiente componente de la canalización o de cortocircuitar la cadena en caso de ser necesario.
En la firma del método Configure
se pueden especificar servicios adicionales, como IWebHostEnvironment
, ILoggerFactory
, o bien todo lo definido en ConfigureServices
. Estos servicios adicionales se insertan si están disponibles.
Para más información sobre cómo usar IApplicationBuilder
y el orden de procesamiento de middleware, vea IApplicationBuilder
.
Configuración de servicios sin inicio
Para configurar los servicios y la canalización de procesamiento de solicitudes sin usar una clase Startup
, llame a los métodos de conveniencia ConfigureServices
y Configure
en el generador de host. Varias llamadas a ConfigureServices
se anexan entre sí. Si hay varias llamadas al método Configure
, se usa la última llamada a 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"];
});
});
});
}
Extensión del inicio con filtros de inicio
Use IStartupFilter:
- Para configurar el middleware al principio o al final de la canalización de middleware Configure de una aplicación sin una llamada explícita a
Use{Middleware}
. ASP.NET Core usaIStartupFilter
para agregar los valores predeterminados al principio de la canalización sin que el creador de la aplicación tenga que registrar explícitamente el middleware predeterminado.IStartupFilter
permite que otro componente llame aUse{Middleware}
en nombre del creador de la aplicación. - Para crear una canalización de métodos
Configure
. IStartupFilter.Configure puede configurar middleware para que se ejecute antes o después del middleware agregado por las bibliotecas.
IStartupFilter
implementa Configure, que recibe y devuelve un elemento Action<IApplicationBuilder>
. IApplicationBuilder define una clase para configurar la canalización de solicitudes de una aplicación. Para más información, vea Creación de una canalización de middleware con IApplicationBuilder.
Cada instancia de IStartupFilter
puede agregar uno o más middleware en la canalización de solicitudes. Los filtros se invocan en el orden en que se agregaron al contenedor de servicios. Los filtros pueden agregar middleware antes o después de pasar el control al siguiente filtro, por lo que se anexan al principio o al final de la canalización de la aplicación.
En el ejemplo siguiente, se muestra cómo registrar un componente de middleware con IStartupFilter
. El componente de middleware RequestSetOptionsMiddleware
establece un valor de opciones de un parámetro de cadena de consulta:
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
está configurado en las clase RequestSetOptionsStartupFilter
:
public class RequestSetOptionsStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestSetOptionsMiddleware>();
next(builder);
};
}
}
IStartupFilter
se registra en el contenedor de servicios en 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>();
});
}
Cuando se proporciona un parámetro de cadena de consulta para option
, el middleware procesa la asignación del valor antes de que el middleware de ASP.NET Core represente la respuesta.
El orden de ejecución de middleware se establece según el orden de registros de IStartupFilter
:
Varias implementaciones de
IStartupFilter
pueden interactuar con los mismos objetos. Si el orden es importante, ordene los registros de servicio deIStartupFilter
para que coincidan con el orden en que se deben ejecutar los middleware.Las bibliotecas pueden agregar middleware con una o varias implementaciones de
IStartupFilter
que se ejecuten antes o después de otro middleware de aplicación registrado conIStartupFilter
. Para invocar un middlewareIStartupFilter
antes de un middleware agregado por el elementoIStartupFilter
de una biblioteca:- Coloque el registro del servicio antes de que la biblioteca se agregue al contenedor de servicios.
- Para la invocación posterior, coloque el registro del servicio después de que se agregue la biblioteca.
Agregar opciones de configuración en el inicio desde un ensamblado externo
Una implementación de IHostingStartup permite agregar mejoras a una aplicación al iniciarla a partir de un ensamblado externo fuera de la clase Startup
de esta. Para obtener más información, consulte Uso de ensamblados de inicio de hospedaje en ASP.NET Core.