--- title: ASP.NET Core Web Host author: guardrex description: Learn about the web host in ASP.NET Core, which is responsible for app startup and lifetime management. ms.author: riande ms.custom: mvc ms.date: 06/19/2018 uid: fundamentals/host/web-host --- # ASP.NET Core Web Host By [Luke Latham](https://github.com/guardrex) ASP.NET Core apps configure and launch a *host*. The host is responsible for app startup and lifetime management. At a minimum, the host configures a server and a request processing pipeline. This topic covers the ASP.NET Core Web Host ([IWebHostBuilder](/dotnet/api/microsoft.aspnetcore.hosting.iwebhostbuilder)), which is useful for hosting web apps. For coverage of the .NET Generic Host ([IHostBuilder](/dotnet/api/microsoft.extensions.hosting.ihostbuilder)), see . ## Set up a host ::: moniker range=">= aspnetcore-2.0" Create a host using an instance of [IWebHostBuilder](/dotnet/api/microsoft.aspnetcore.hosting.iwebhostbuilder). This is typically performed in the app's entry point, the `Main` method. In the project templates, `Main` is located in *Program.cs*. A typical *Program.cs* calls [CreateDefaultBuilder](/dotnet/api/microsoft.aspnetcore.webhost.createdefaultbuilder) to start setting up a host: ```csharp public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup(); } ``` `CreateDefaultBuilder` performs the following tasks: * Configures [Kestrel](xref:fundamentals/servers/kestrel) as the web server and configures the server using the app's hosting configuration providers. For the Kestrel default options, see . * Sets the content root to the path returned by [Directory.GetCurrentDirectory](/dotnet/api/system.io.directory.getcurrentdirectory). * Loads [host configuration](#host-configuration-values) from: * Environment variables prefixed with `ASPNETCORE_` (for example, `ASPNETCORE_ENVIRONMENT`). * Command-line arguments. * Loads app configuration from: * *appsettings.json*. * *appsettings.{Environment}.json*. * [User secrets](xref:security/app-secrets) when the app runs in the `Development` environment using the entry assembly. * Environment variables. * Command-line arguments. * Configures [logging](xref:fundamentals/logging/index) for console and debug output. Logging includes [log filtering](xref:fundamentals/logging/index#log-filtering) rules specified in a Logging configuration section of an *appsettings.json* or *appsettings.{Environment}.json* file. * When running behind IIS, enables [IIS integration](xref:host-and-deploy/iis/index). Configures the base path and port the server listens on when using the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module). The module creates a reverse proxy between IIS and Kestrel. Also configures the app to [capture startup errors](#capture-startup-errors). For the IIS default options, see . * Sets [ServiceProviderOptions.ValidateScopes](/dotnet/api/microsoft.extensions.dependencyinjection.serviceprovideroptions.validatescopes) to `true` if the app's environment is Development. For more information, see [Scope validation](#scope-validation). The configuration defined by `CreateDefaultBuilder` can be overridden and augmented by [ConfigureAppConfiguration](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.configureappconfiguration), [ConfigureLogging](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.configurelogging), and other methods and extension methods of [IWebHostBuilder](/dotnet/api/microsoft.aspnetcore.hosting.iwebhostbuilder). A few examples follow: * [ConfigureAppConfiguration](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.configureappconfiguration) is used to specify additional `IConfiguration` for the app. The following `ConfigureAppConfiguration` call adds a delegate to include app configuration in the *appsettings.xml* file. `ConfigureAppConfiguration` may be called multiple times. Note that this configuration doesn't apply to the host (for example, server URLs or environment). See the [Host configuration values](#host-configuration-values) section. ```csharp WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true); }) ... ``` * The following `ConfigureLogging` call adds a delegate to configure the minimum logging level ([SetMinimumLevel](/dotnet/api/microsoft.extensions.logging.loggingbuilderextensions.setminimumlevel)) to [LogLevel.Warning](/dotnet/api/microsoft.extensions.logging.loglevel). This setting overrides the settings in *appsettings.Development.json* (`LogLevel.Debug`) and *appsettings.Production.json* (`LogLevel.Error`) configured by `CreateDefaultBuilder`. `ConfigureLogging` may be called multiple times. ```csharp WebHost.CreateDefaultBuilder(args) .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Warning); }) ... ``` * The following call to [UseKestrel](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderkestrelextensions.usekestrel) overrides the default [Limits.MaxRequestBodySize](/dotnet/api/microsoft.aspnetcore.server.kestrel.core.kestrelserverlimits.maxrequestbodysize) of 30,000,000 bytes established when Kestrel was configured by `CreateDefaultBuilder`: ```csharp WebHost.CreateDefaultBuilder(args) .UseKestrel(options => { options.Limits.MaxRequestBodySize = 20000000; }); ... ``` The *content root* determines where the host searches for content files, such as MVC view files. When the app is started from the project's root folder, the project's root folder is used as the content root. This is the default used in [Visual Studio](https://www.visualstudio.com/) and the [dotnet new templates](/dotnet/core/tools/dotnet-new). For more information on app configuration, see . > [!NOTE] > As an alternative to using the static `CreateDefaultBuilder` method, creating a host from [WebHostBuilder](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilder) is a supported approach with ASP.NET Core 2.x. For more information, see the ASP.NET Core 1.x tab. ::: moniker-end ::: moniker range="< aspnetcore-2.0" Create a host using an instance of [WebHostBuilder](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilder). Creating a host is typically performed in the app's entry point, the `Main` method. In the project templates, `Main` is located in *Program.cs*: ```csharp public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() .Build(); } ``` `WebHostBuilder` requires a [server that implements IServer](xref:fundamentals/servers/index). The built-in servers are [Kestrel](xref:fundamentals/servers/kestrel) and [HTTP.sys](xref:fundamentals/servers/httpsys) (prior to the release of ASP.NET Core 2.0, HTTP.sys was called [WebListener](xref:fundamentals/servers/weblistener)). In this example, the [UseKestrel extension method](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderkestrelextensions.usekestrel?view=aspnetcore-1.1) specifies the Kestrel server. The *content root* determines where the host searches for content files, such as MVC view files. The default content root is obtained for `UseContentRoot` by [Directory.GetCurrentDirectory](/dotnet/api/system.io.directory.getcurrentdirectory?view=netcore-1.1). When the app is started from the project's root folder, the project's root folder is used as the content root. This is the default used in [Visual Studio](https://www.visualstudio.com/) and the [dotnet new templates](/dotnet/core/tools/dotnet-new). To use IIS as a reverse proxy, call [UseIISIntegration](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderiisextensions) as part of building the host. `UseIISIntegration` doesn't configure a *server*, like [UseKestrel](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderkestrelextensions.usekestrel?view=aspnetcore-1.1) does. `UseIISIntegration` configures the base path and port the server listens on when using the [ASP.NET Core Module](xref:fundamentals/servers/aspnet-core-module) to create a reverse proxy between Kestrel and IIS. To use IIS with ASP.NET Core, `UseKestrel` and `UseIISIntegration` must be specified. `UseIISIntegration` only activates when running behind IIS or IIS Express. For more information, see and . A minimal implementation that configures a host (and an ASP.NET Core app) includes specifying a server and configuration of the app's request pipeline: ```csharp var host = new WebHostBuilder() .UseKestrel() .Configure(app => { app.Run(context => context.Response.WriteAsync("Hello World!")); }) .Build(); host.Run(); ``` ::: moniker-end When setting up a host, [Configure](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.configure?view=aspnetcore-1.1) and [ConfigureServices](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilder.configureservices?view=aspnetcore-1.1) methods can be provided. If a `Startup` class is specified, it must define a `Configure` method. For more information, see . Multiple calls to `ConfigureServices` append to one another. Multiple calls to `Configure` or `UseStartup` on the `WebHostBuilder` replace previous settings. ## Host configuration values [WebHostBuilder](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilder) relies on the following approaches to set the host configuration values: * Host builder configuration, which includes environment variables with the format `ASPNETCORE_{configurationKey}`. For example, `ASPNETCORE_ENVIRONMENT`. * Extensions such as [UseContentRoot](/dotnet/api/microsoft.aspnetcore.hosting.hostingabstractionswebhostbuilderextensions.usecontentroot) and [UseConfiguration](/dotnet/api/microsoft.aspnetcore.hosting.hostingabstractionswebhostbuilderextensions.useconfiguration) (see the [Override configuration](#override-configuration) section). * [UseSetting](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilder.usesetting) and the associated key. When setting a value with `UseSetting`, the value is set as a string regardless of the type. The host uses whichever option sets a value last. For more information, see [Override configuration](#override-configuration) in the next section. ### Application Key (Name) The [IHostingEnvironment.ApplicationName](/dotnet/api/microsoft.extensions.hosting.ihostingenvironment.applicationname) property is automatically set when [UseStartup](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.usestartup) or [Configure](/dotnet/api/microsoft.aspnetcore.hosting.istartup.configure) is called during host construction. The value is set to the name of the assembly containing the app's entry point. To set the value explicitly, use the [WebHostDefaults.ApplicationKey](/dotnet/api/microsoft.aspnetcore.hosting.webhostdefaults.applicationkey): **Key**: applicationName **Type**: *string* **Default**: The name of the assembly containing the app's entry point. **Set using**: `UseSetting` **Environment variable**: `ASPNETCORE_APPLICATIONKEY` ::: moniker range=">= aspnetcore-2.1" ```csharp WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName") ``` ::: moniker-end ::: moniker range="< aspnetcore-2.1" ```csharp var host = new WebHostBuilder() .UseSetting("applicationName", "CustomApplicationName") ``` ::: moniker-end ### Capture Startup Errors This setting controls the capture of startup errors. **Key**: captureStartupErrors **Type**: *bool* (`true` or `1`) **Default**: Defaults to `false` unless the app runs with Kestrel behind IIS, where the default is `true`. **Set using**: `CaptureStartupErrors` **Environment variable**: `ASPNETCORE_CAPTURESTARTUPERRORS` When `false`, errors during startup result in the host exiting. When `true`, the host captures exceptions during startup and attempts to start the server. ::: moniker range=">= aspnetcore-2.0" ```csharp WebHost.CreateDefaultBuilder(args) .CaptureStartupErrors(true) ``` ::: moniker-end ::: moniker range="< aspnetcore-2.0" ```csharp var host = new WebHostBuilder() .CaptureStartupErrors(true) ``` ::: moniker-end ### Content Root This setting determines where ASP.NET Core begins searching for content files, such as MVC views. **Key**: contentRoot **Type**: *string* **Default**: Defaults to the folder where the app assembly resides. **Set using**: `UseContentRoot` **Environment variable**: `ASPNETCORE_CONTENTROOT` The content root is also used as the base path for the [Web Root setting](#web-root). If the path doesn't exist, the host fails to start. ::: moniker range=">= aspnetcore-2.0" ```csharp WebHost.CreateDefaultBuilder(args) .UseContentRoot("c:\\") ``` ::: moniker-end ::: moniker range="< aspnetcore-2.0" ```csharp var host = new WebHostBuilder() .UseContentRoot("c:\\") ``` ::: moniker-end ### Detailed Errors Determines if detailed errors should be captured. **Key**: detailedErrors **Type**: *bool* (`true` or `1`) **Default**: false **Set using**: `UseSetting` **Environment variable**: `ASPNETCORE_DETAILEDERRORS` When enabled (or when the Environment is set to `Development`), the app captures detailed exceptions. ::: moniker range=">= aspnetcore-2.0" ```csharp WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.DetailedErrorsKey, "true") ``` ::: moniker-end ::: moniker range="< aspnetcore-2.0" ```csharp var host = new WebHostBuilder() .UseSetting(WebHostDefaults.DetailedErrorsKey, "true") ``` ::: moniker-end ### Environment Sets the app's environment. **Key**: environment **Type**: *string* **Default**: Production **Set using**: `UseEnvironment` **Environment variable**: `ASPNETCORE_ENVIRONMENT` The environment can be set to any value. Framework-defined values include `Development`, `Staging`, and `Production`. Values aren't case sensitive. By default, the *Environment* is read from the `ASPNETCORE_ENVIRONMENT` environment variable. When using [Visual Studio](https://www.visualstudio.com/), environment variables may be set in the *launchSettings.json* file. For more information, see . ::: moniker range=">= aspnetcore-2.0" ```csharp WebHost.CreateDefaultBuilder(args) .UseEnvironment(EnvironmentName.Development) ``` ::: moniker-end ::: moniker range="< aspnetcore-2.0" ```csharp var host = new WebHostBuilder() .UseEnvironment(EnvironmentName.Development) ``` ::: moniker-end ::: moniker range=">= aspnetcore-2.0" ### Hosting Startup Assemblies Sets the app's hosting startup assemblies. **Key**: hostingStartupAssemblies **Type**: *string* **Default**: Empty string **Set using**: `UseSetting` **Environment variable**: `ASPNETCORE_HOSTINGSTARTUPASSEMBLIES` A semicolon-delimited string of hosting startup assemblies to load on startup. Although the configuration value defaults to an empty string, the hosting startup assemblies always include the app's assembly. When hosting startup assemblies are provided, they're added to the app's assembly for loading when the app builds its common services during startup. ```csharp WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2") ``` ::: moniker-end ::: moniker range=">= aspnetcore-2.1" ### HTTPS Port Set the HTTPS redirect port. Used in [enforcing HTTPS](xref:security/enforcing-ssl). **Key**: https_port **Type**: *string* **Default**: A default value isn't set. **Set using**: `UseSetting` **Environment variable**: `ASPNETCORE_HTTPS_PORT` ```csharp WebHost.CreateDefaultBuilder(args) .UseSetting("https_port", "8080") ``` ### Hosting Startup Exclude Assemblies DESCRIPTION **Key**: hostingStartupExcludeAssemblies **Type**: *string* **Default**: Empty string **Set using**: `UseSetting` **Environment variable**: `ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES` A semicolon-delimited string of hosting startup assemblies to exclude on startup. ```csharp WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2") ``` ::: moniker-end ::: moniker range=">= aspnetcore-2.0" ### Prefer Hosting URLs Indicates whether the host should listen on the URLs configured with the `WebHostBuilder` instead of those configured with the `IServer` implementation. **Key**: preferHostingUrls **Type**: *bool* (`true` or `1`) **Default**: true **Set using**: `PreferHostingUrls` **Environment variable**: `ASPNETCORE_PREFERHOSTINGURLS` ```csharp WebHost.CreateDefaultBuilder(args) .PreferHostingUrls(false) ``` ::: moniker-end ::: moniker range=">= aspnetcore-2.0" ### Prevent Hosting Startup Prevents the automatic loading of hosting startup assemblies, including hosting startup assemblies configured by the app's assembly. For more information, see . **Key**: preventHostingStartup **Type**: *bool* (`true` or `1`) **Default**: false **Set using**: `UseSetting` **Environment variable**: `ASPNETCORE_PREVENTHOSTINGSTARTUP` ```csharp WebHost.CreateDefaultBuilder(args) .UseSetting(WebHostDefaults.PreventHostingStartupKey, "true") ``` ::: moniker-end ### Server URLs Indicates the IP addresses or host addresses with ports and protocols that the server should listen on for requests. **Key**: urls **Type**: *string* **Default**: http://localhost:5000 **Set using**: `UseUrls` **Environment variable**: `ASPNETCORE_URLS` Set to a semicolon-separated (;) list of URL prefixes to which the server should respond. For example, `http://localhost:123`. Use "\*" to indicate that the server should listen for requests on any IP address or hostname using the specified port and protocol (for example, `http://*:5000`). The protocol (`http://` or `https://`) must be included with each URL. Supported formats vary between servers. ::: moniker range=">= aspnetcore-2.0" ```csharp WebHost.CreateDefaultBuilder(args) .UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002") ``` Kestrel has its own endpoint configuration API. For more information, see . ::: moniker-end ::: moniker range="< aspnetcore-2.0" ```csharp var host = new WebHostBuilder() .UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002") ``` ::: moniker-end ::: moniker range=">= aspnetcore-2.0" ### Shutdown Timeout Specifies the amount of time to wait for the web host to shut down. **Key**: shutdownTimeoutSeconds **Type**: *int* **Default**: 5 **Set using**: `UseShutdownTimeout` **Environment variable**: `ASPNETCORE_SHUTDOWNTIMEOUTSECONDS` Although the key accepts an *int* with `UseSetting` (for example, `.UseSetting(WebHostDefaults.ShutdownTimeoutKey, "10")`), the [UseShutdownTimeout](/dotnet/api/microsoft.aspnetcore.hosting.hostingabstractionswebhostbuilderextensions.useshutdowntimeout) extension method takes a [TimeSpan](/dotnet/api/system.timespan). During the timeout period, hosting: * Triggers [IApplicationLifetime.ApplicationStopping](/dotnet/api/microsoft.aspnetcore.hosting.iapplicationlifetime.applicationstopping). * Attempts to stop hosted services, logging any errors for services that fail to stop. If the timeout period expires before all of the hosted services stop, any remaining active services are stopped when the app shuts down. The services stop even if they haven't finished processing. If services require additional time to stop, increase the timeout. ```csharp WebHost.CreateDefaultBuilder(args) .UseShutdownTimeout(TimeSpan.FromSeconds(10)) ``` ::: moniker-end ### Startup Assembly Determines the assembly to search for the `Startup` class. **Key**: startupAssembly **Type**: *string* **Default**: The app's assembly **Set using**: `UseStartup` **Environment variable**: `ASPNETCORE_STARTUPASSEMBLY` The assembly by name (`string`) or type (`TStartup`) can be referenced. If multiple `UseStartup` methods are called, the last one takes precedence. ::: moniker range=">= aspnetcore-2.0" ```csharp WebHost.CreateDefaultBuilder(args) .UseStartup("StartupAssemblyName") ``` ```csharp WebHost.CreateDefaultBuilder(args) .UseStartup() ``` ::: moniker-end ::: moniker range="< aspnetcore-2.0" ```csharp var host = new WebHostBuilder() .UseStartup("StartupAssemblyName") ``` ```csharp var host = new WebHostBuilder() .UseStartup() ``` ::: moniker-end ### Web Root Sets the relative path to the app's static assets. **Key**: webroot **Type**: *string* **Default**: If not specified, the default is "(Content Root)/wwwroot", if the path exists. If the path doesn't exist, then a no-op file provider is used. **Set using**: `UseWebRoot` **Environment variable**: `ASPNETCORE_WEBROOT` ::: moniker range=">= aspnetcore-2.0" ```csharp WebHost.CreateDefaultBuilder(args) .UseWebRoot("public") ``` ::: moniker-end ::: moniker range="< aspnetcore-2.0" ```csharp var host = new WebHostBuilder() .UseWebRoot("public") ``` ::: moniker-end ## Override configuration Use [Configuration](xref:fundamentals/configuration/index) to configure the web host. In the following example, host configuration is optionally specified in a *hostsettings.json* file. Any configuration loaded from the *hostsettings.json* file may be overridden by command-line arguments. The built configuration (in `config`) is used to configure the host with [UseConfiguration](/dotnet/api/microsoft.aspnetcore.hosting.hostingabstractionswebhostbuilderextensions.useconfiguration). `IWebHostBuilder` configuration is added to the app's configuration, but the converse isn't true—`ConfigureAppConfiguration` doesn't affect the `IWebHostBuilder` configuration. ::: moniker range=">= aspnetcore-2.0" Overriding the configuration provided by `UseUrls` with *hostsettings.json* config first, command-line argument config second: ```csharp public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("hostsettings.json", optional: true) .AddCommandLine(args) .Build(); return WebHost.CreateDefaultBuilder(args) .UseUrls("http://*:5000") .UseConfiguration(config) .Configure(app => { app.Run(context => context.Response.WriteAsync("Hello, World!")); }) .Build(); } } ``` *hostsettings.json*: ```json { urls: "http://*:5005" } ``` ::: moniker-end ::: moniker range="< aspnetcore-2.0" Overriding the configuration provided by `UseUrls` with *hostsettings.json* config first, command-line argument config second: ```csharp public class Program { public static void Main(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("hostsettings.json", optional: true) .AddCommandLine(args) .Build(); var host = new WebHostBuilder() .UseUrls("http://*:5000") .UseConfiguration(config) .UseKestrel() .Configure(app => { app.Run(context => context.Response.WriteAsync("Hello, World!")); }) .Build(); host.Run(); } } ``` *hostsettings.json*: ```json { urls: "http://*:5005" } ``` ::: moniker-end > [!NOTE] > The [UseConfiguration](/dotnet/api/microsoft.aspnetcore.hosting.hostingabstractionswebhostbuilderextensions.useconfiguration) extension method isn't currently capable of parsing a configuration section returned by `GetSection` (for example, `.UseConfiguration(Configuration.GetSection("section"))`. The `GetSection` method filters the configuration keys to the section requested but leaves the section name on the keys (for example, `section:urls`, `section:environment`). The `UseConfiguration` method expects the keys to match the `WebHostBuilder` keys (for example, `urls`, `environment`). The presence of the section name on the keys prevents the section's values from configuring the host. This issue will be addressed in an upcoming release. For more information and workarounds, see [Passing configuration section into WebHostBuilder.UseConfiguration uses full keys](https://github.com/aspnet/Hosting/issues/839). > > `UseConfiguration` only copies keys from the provided `IConfiguration` to the host builder configuration. Therefore, setting `reloadOnChange: true` for JSON, INI, and XML settings files has no effect. To specify the host run on a particular URL, the desired value can be passed in from a command prompt when executing [dotnet run](/dotnet/core/tools/dotnet-run). The command-line argument overrides the `urls` value from the *hostsettings.json* file, and the server listens on port 8080: ```console dotnet run --urls "http://*:8080" ``` ## Manage the host ::: moniker range=">= aspnetcore-2.0" **Run** The `Run` method starts the web app and blocks the calling thread until the host is shut down: ```csharp host.Run(); ``` **Start** Run the host in a non-blocking manner by calling its `Start` method: ```csharp using (host) { host.Start(); Console.ReadLine(); } ``` If a list of URLs is passed to the `Start` method, it listens on the URLs specified: ```csharp var urls = new List() { "http://*:5000", "http://localhost:5001" }; var host = new WebHostBuilder() .UseKestrel() .UseStartup() .Start(urls.ToArray()); using (host) { Console.ReadLine(); } ``` The app can initialize and start a new host using the pre-configured defaults of `CreateDefaultBuilder` using a static convenience method. These methods start the server without console output and with [WaitForShutdown](/dotnet/api/microsoft.aspnetcore.hosting.webhostextensions.waitforshutdown) wait for a break (Ctrl-C/SIGINT or SIGTERM): **Start(RequestDelegate app)** Start with a `RequestDelegate`: ```csharp using (var host = WebHost.Start(app => app.Response.WriteAsync("Hello, World!"))) { Console.WriteLine("Use Ctrl-C to shutdown the host..."); host.WaitForShutdown(); } ``` Make a request in the browser to `http://localhost:5000` to receive the response "Hello World!" `WaitForShutdown` blocks until a break (Ctrl-C/SIGINT or SIGTERM) is issued. The app displays the `Console.WriteLine` message and waits for a keypress to exit. **Start(string url, RequestDelegate app)** Start with a URL and `RequestDelegate`: ```csharp using (var host = WebHost.Start("http://localhost:8080", app => app.Response.WriteAsync("Hello, World!"))) { Console.WriteLine("Use Ctrl-C to shutdown the host..."); host.WaitForShutdown(); } ``` Produces the same result as **Start(RequestDelegate app)**, except the app responds on `http://localhost:8080`. **Start(Action<IRouteBuilder> routeBuilder)** Use an instance of `IRouteBuilder` ([Microsoft.AspNetCore.Routing](https://www.nuget.org/packages/Microsoft.AspNetCore.Routing/)) to use routing middleware: ```csharp using (var host = WebHost.Start(router => router .MapGet("hello/{name}", (req, res, data) => res.WriteAsync($"Hello, {data.Values["name"]}!")) .MapGet("buenosdias/{name}", (req, res, data) => res.WriteAsync($"Buenos dias, {data.Values["name"]}!")) .MapGet("throw/{message?}", (req, res, data) => throw new Exception((string)data.Values["message"] ?? "Uh oh!")) .MapGet("{greeting}/{name}", (req, res, data) => res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}!")) .MapGet("", (req, res, data) => res.WriteAsync("Hello, World!")))) { Console.WriteLine("Use Ctrl-C to shutdown the host..."); host.WaitForShutdown(); } ``` Use the following browser requests with the example: | Request | Response | | ------------------------------------------ | ---------------------------------------- | | `http://localhost:5000/hello/Martin` | Hello, Martin! | | `http://localhost:5000/buenosdias/Catrina` | Buenos dias, Catrina! | | `http://localhost:5000/throw/ooops!` | Throws an exception with string "ooops!" | | `http://localhost:5000/throw` | Throws an exception with string "Uh oh!" | | `http://localhost:5000/Sante/Kevin` | Sante, Kevin! | | `http://localhost:5000` | Hello World! | `WaitForShutdown` blocks until a break (Ctrl-C/SIGINT or SIGTERM) is issued. The app displays the `Console.WriteLine` message and waits for a keypress to exit. **Start(string url, Action<IRouteBuilder> routeBuilder)** Use a URL and an instance of `IRouteBuilder`: ```csharp using (var host = WebHost.Start("http://localhost:8080", router => router .MapGet("hello/{name}", (req, res, data) => res.WriteAsync($"Hello, {data.Values["name"]}!")) .MapGet("buenosdias/{name}", (req, res, data) => res.WriteAsync($"Buenos dias, {data.Values["name"]}!")) .MapGet("throw/{message?}", (req, res, data) => throw new Exception((string)data.Values["message"] ?? "Uh oh!")) .MapGet("{greeting}/{name}", (req, res, data) => res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}!")) .MapGet("", (req, res, data) => res.WriteAsync("Hello, World!")))) { Console.WriteLine("Use Ctrl-C to shut down the host..."); host.WaitForShutdown(); } ``` Produces the same result as **Start(Action<IRouteBuilder> routeBuilder)**, except the app responds at `http://localhost:8080`. **StartWith(Action<IApplicationBuilder> app)** Provide a delegate to configure an `IApplicationBuilder`: ```csharp using (var host = WebHost.StartWith(app => app.Use(next => { return async context => { await context.Response.WriteAsync("Hello World!"); }; }))) { Console.WriteLine("Use Ctrl-C to shut down the host..."); host.WaitForShutdown(); } ``` Make a request in the browser to `http://localhost:5000` to receive the response "Hello World!" `WaitForShutdown` blocks until a break (Ctrl-C/SIGINT or SIGTERM) is issued. The app displays the `Console.WriteLine` message and waits for a keypress to exit. **StartWith(string url, Action<IApplicationBuilder> app)** Provide a URL and a delegate to configure an `IApplicationBuilder`: ```csharp using (var host = WebHost.StartWith("http://localhost:8080", app => app.Use(next => { return async context => { await context.Response.WriteAsync("Hello World!"); }; }))) { Console.WriteLine("Use Ctrl-C to shut down the host..."); host.WaitForShutdown(); } ``` Produces the same result as **StartWith(Action<IApplicationBuilder> app)**, except the app responds on `http://localhost:8080`. ::: moniker-end ::: moniker range="< aspnetcore-2.0" **Run** The `Run` method starts the web app and blocks the calling thread until the host is shut down: ```csharp host.Run(); ``` **Start** Run the host in a non-blocking manner by calling its `Start` method: ```csharp using (host) { host.Start(); Console.ReadLine(); } ``` If a list of URLs is passed to the `Start` method, it listens on the URLs specified: ```csharp var urls = new List() { "http://*:5000", "http://localhost:5001" }; var host = new WebHostBuilder() .UseKestrel() .UseStartup() .Start(urls.ToArray()); using (host) { Console.ReadLine(); } ``` ::: moniker-end ## IHostingEnvironment interface The [IHostingEnvironment interface](/dotnet/api/microsoft.aspnetcore.hosting.ihostingenvironment) provides information about the app's web hosting environment. Use [constructor injection](xref:fundamentals/dependency-injection) to obtain the `IHostingEnvironment` in order to use its properties and extension methods: ```csharp public class CustomFileReader { private readonly IHostingEnvironment _env; public CustomFileReader(IHostingEnvironment env) { _env = env; } public string ReadFile(string filePath) { var fileProvider = _env.WebRootFileProvider; // Process the file here } } ``` A [convention-based approach](xref:fundamentals/environments#environment-based-startup-class-and-methods) can be used to configure the app at startup based on the environment. Alternatively, inject the `IHostingEnvironment` into the `Startup` constructor for use in `ConfigureServices`: ```csharp public class Startup { public Startup(IHostingEnvironment env) { HostingEnvironment = env; } public IHostingEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services) { if (HostingEnvironment.IsDevelopment()) { // Development configuration } else { // Staging/Production configuration } var contentRootPath = HostingEnvironment.ContentRootPath; } } ``` > [!NOTE] > In addition to the `IsDevelopment` extension method, `IHostingEnvironment` offers `IsStaging`, `IsProduction`, and `IsEnvironment(string environmentName)` methods. For more information, see . The `IHostingEnvironment` service can also be injected directly into the `Configure` method for setting up the processing pipeline: ```csharp public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { // In Development, use the developer exception page app.UseDeveloperExceptionPage(); } else { // In Staging/Production, route exceptions to /error app.UseExceptionHandler("/error"); } var contentRootPath = env.ContentRootPath; } ``` `IHostingEnvironment` can be injected into the `Invoke` method when creating custom [middleware](xref:fundamentals/middleware/index#write-middleware): ```csharp public async Task Invoke(HttpContext context, IHostingEnvironment env) { if (env.IsDevelopment()) { // Configure middleware for Development } else { // Configure middleware for Staging/Production } var contentRootPath = env.ContentRootPath; } ``` ## IApplicationLifetime interface [IApplicationLifetime](/dotnet/api/microsoft.aspnetcore.hosting.iapplicationlifetime) allows for post-startup and shutdown activities. Three properties on the interface are cancellation tokens used to register `Action` methods that define startup and shutdown events. | Cancellation Token | Triggered when… | | --------------------- | --------------------- | | [ApplicationStarted](/dotnet/api/microsoft.extensions.hosting.iapplicationlifetime.applicationstarted) | The host has fully started. | | [ApplicationStopped](/dotnet/api/microsoft.extensions.hosting.iapplicationlifetime.applicationstopped) | The host is completing a graceful shutdown. All requests should be processed. Shutdown blocks until this event completes. | | [ApplicationStopping](/dotnet/api/microsoft.extensions.hosting.iapplicationlifetime.applicationstopping) | The host is performing a graceful shutdown. Requests may still be processing. Shutdown blocks until this event completes. | ```csharp public class Startup { public void Configure(IApplicationBuilder app, IApplicationLifetime appLifetime) { appLifetime.ApplicationStarted.Register(OnStarted); appLifetime.ApplicationStopping.Register(OnStopping); appLifetime.ApplicationStopped.Register(OnStopped); Console.CancelKeyPress += (sender, eventArgs) => { appLifetime.StopApplication(); // Don't terminate the process immediately, wait for the Main thread to exit gracefully. eventArgs.Cancel = true; }; } private void OnStarted() { // Perform post-startup activities here } private void OnStopping() { // Perform on-stopping activities here } private void OnStopped() { // Perform post-stopped activities here } } ``` [StopApplication](/dotnet/api/microsoft.aspnetcore.hosting.iapplicationlifetime.stopapplication) requests termination of the app. The following class uses `StopApplication` to gracefully shut down an app when the class's `Shutdown` method is called: ```csharp public class MyClass { private readonly IApplicationLifetime _appLifetime; public MyClass(IApplicationLifetime appLifetime) { _appLifetime = appLifetime; } public void Shutdown() { _appLifetime.StopApplication(); } } ``` ## Scope validation ::: moniker range=">= aspnetcore-2.0" [CreateDefaultBuilder](/dotnet/api/microsoft.aspnetcore.webhost.createdefaultbuilder) sets [ServiceProviderOptions.ValidateScopes](/dotnet/api/microsoft.extensions.dependencyinjection.serviceprovideroptions.validatescopes) to `true` if the app's environment is Development. ::: moniker-end When `ValidateScopes` is set to `true`, the default service provider performs checks to verify that: * Scoped services aren't directly or indirectly resolved from the root service provider. * Scoped services aren't directly or indirectly injected into singletons. The root service provider is created when [BuildServiceProvider](/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectioncontainerbuilderextensions.buildserviceprovider) is called. The root service provider's lifetime corresponds to the app/server's lifetime when the provider starts with the app and is disposed when the app shuts down. Scoped services are disposed by the container that created them. If a scoped service is created in the root container, the service's lifetime is effectively promoted to singleton because it's only disposed by the root container when app/server is shut down. Validating service scopes catches these situations when `BuildServiceProvider` is called. To always validate scopes, including in the Production environment, configure the [ServiceProviderOptions](/dotnet/api/microsoft.extensions.dependencyinjection.serviceprovideroptions) with [UseDefaultServiceProvider](/dotnet/api/microsoft.aspnetcore.hosting.webhostbuilderextensions.usedefaultserviceprovider) on the host builder: ```csharp WebHost.CreateDefaultBuilder(args) .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = true; }) ``` ::: moniker range="= aspnetcore-2.0" ## Troubleshooting System.ArgumentException **The following only applies to ASP.NET Core 2.0 apps when the app doesn't call `UseStartup` or `Configure`.** A host may be built by injecting `IStartup` directly into the dependency injection container rather than calling `UseStartup` or `Configure`: ```csharp services.AddSingleton(); ``` If the host is built this way, the following error may occur: ``` Unhandled Exception: System.ArgumentException: A valid non-empty application name must be provided. ``` This occurs because the app name (the name of the current assembly) is required to scan for `HostingStartupAttributes`. If the app manually injects `IStartup` into the dependency injection container, add the following call to `WebHostBuilder` with the assembly name specified: ```csharp WebHost.CreateDefaultBuilder(args) .UseSetting("applicationName", "AssemblyName") ``` Alternatively, add a dummy `Configure` to the `WebHostBuilder`, which sets the app name automatically: ```csharp WebHost.CreateDefaultBuilder(args) .Configure(_ => { }) ``` For more information, see [Announcements: Microsoft.Extensions.PlatformAbstractions has been removed (comment)](https://github.com/aspnet/Announcements/issues/237#issuecomment-323786938) and the [StartupInjection sample](https://github.com/aspnet/Hosting/blob/8377d226f1e6e1a97dabdb6769a845eeccc829ed/samples/SampleStartups/StartupInjection.cs). ::: moniker-end ## Additional resources * * * *