Fundamentals - Host - Web Host
In this article
Set up a host
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
-
Configures Kestrel server as the web server using the app's hosting configuration providers. For the Kestrel server's default options, see
Configure
options for the ASP.NET Core Kestrel web server. -
Sets the content root to the path returned by
Directory.GetCurrentDirectory
. -
Loads host configuration from:
-
Environment variables prefixed with
ASPNETCORE_
(for example,ASPNETCORE_ENVIRONMENT
). -
Command-line arguments.
-
-
Loads app configuration in the following order from:
-
appsettings.json
. -
appsettings.{Environment}.json
. -
User secrets when the app runs in the
Development
environment using the entry assembly. -
Environment variables.
-
Command-line arguments.
-
-
Configures logging for console and debug output. Logging includes log filtering rules specified in a Logging configuration section of an
appsettings.json
orappsettings.{Environment}.json
file. -
When running behind IIS with the ASP.NET Core Module,
CreateDefaultBuilder
enables IIS Integration, which configures the app's base address and port. IIS Integration also configures the app to capture startup errors. For the IIS default options, see Host ASP.NET Core on Windows with IIS. -
Sets ServiceProviderOptions.ValidateScopes to
true
if the app's environment isDevelopment
. For more information, see Scope validation. -
ConfigureAppConfiguration
is used to specify additionalIConfiguration
for the app. The followingConfigureAppConfiguration
call adds a delegate to include app configuration in theappsettings.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 section.
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) toLogLevel.Warning
. This setting overrides the settings inappsettings.Development.json
(LogLevel.Debug) andappsettings.Production.json
(LogLevel.Error) configured byCreateDefaultBuilder
.ConfigureLogging
may be called multiple times.
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Warning);
})
...
- The following call to
ConfigureKestrel
overrides the defaultLimits.MaxRequestBodySize
of 30,000,000 bytes established when Kestrel was configured byCreateDefaultBuilder
:
WebHost.CreateDefaultBuilder(args)
.ConfigureKestrel((context, options) =>
{
options.Limits.MaxRequestBodySize = 20000000;
});
Note As an alternative to using the static
CreateDefaultBuilder
method, creating a host fromWebHostBuilder
is a supported approach with ASP.NET Core 2.x.
Host configuration values
-
Host builder configuration, which includes environment variables with the format
ASPNETCORE_
{configurationKey}. For example,ASPNETCORE_ENVIRONMENT
. -
Extensions such as
UseContentRoot
and UseConfiguration (see the Override configuration section). -
UseSetting
and the associated key. When setting a value withUseSetting
, the value is set as astring
regardless of the type.
Application Key (Name)
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")
Startup
Errors
Capture WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
Content root
WebHost.CreateDefaultBuilder(args)
.UseContentRoot("c:\\<content-root>")
-
Fundamentals: Content root
-
Web root
Detailed Errors
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.DetailedErrorsKey, "true")
Environment
WebHost.CreateDefaultBuilder(args)
.UseEnvironment(EnvironmentName.Development)
Startup
Assemblies
Hosting WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2")
HTTPS Port
WebHost.CreateDefaultBuilder(args)
.UseSetting("https_port", "8080")
Startup
Exclude Assemblies
Hosting WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2")
Prefer Hosting URLs
WebHost.CreateDefaultBuilder(args)
.PreferHostingUrls(true)
Startup
Prevent Hosting WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.PreventHostingStartupKey, "true")
Server URLs
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")
Shutdown
Timeout
-
Triggers IApplicationLifetime.ApplicationStopping.
-
Attempts to stop hosted services, logging any errors for services that fail to stop.
WebHost.CreateDefaultBuilder(args)
.UseShutdownTimeout(TimeSpan.FromSeconds(10))
Startup
Assembly
WebHost.CreateDefaultBuilder(args)
.UseStartup("StartupAssemblyName")
WebHost.CreateDefaultBuilder(args)
.UseStartup<TStartup>()
Web root
WebHost.CreateDefaultBuilder(args)
.UseWebRoot("public")
-
Fundamentals: Web root
-
Content root
Override configuration
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!"));
});
}
}
{
urls: "http://*:5005"
}
Note UseConfiguration only copies keys from the provided
IConfiguration
to the host builder configuration. Therefore, settingreloadOnChange:
true`````` for JSON, INI, and XML settings files has no effect.
dotnet run --urls "http://*:8080"
Manage the host
host.Run();
using (host)
{
host.Start();
Console.ReadLine();
}
var urls = new List<string>()
{
"http://*:5000",
"http://localhost:5001"
};
var host = new WebHostBuilder()
.UseKestrel()
.UseStartup<Startup>()
.Start(urls.ToArray());
using (host)
{
Console.ReadLine();
}
using (var host = WebHost.Start(app => app.Response.WriteAsync("Hello, World!")))
{
Console.WriteLine("Use Ctrl-C to shutdown the host...");
host.WaitForShutdown();
}
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();
}
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();
}
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! |
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();
}
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();
}
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();
}
IWebHostEnvironment
interface
public class CustomFileReader
{
private readonly IWebHostEnvironment _env;
public CustomFileReader(IWebHostEnvironment env)
{
_env = env;
}
public string ReadFile(string filePath)
{
var fileProvider = _env.WebRootFileProvider;
// Process the file here
}
}
public class Startup
{
public Startup(IWebHostEnvironment env)
{
HostingEnvironment = env;
}
public IWebHostEnvironment 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,IWebHostEnvironment
offersIsStaging
,IsProduction
, andIsEnvironment(string environmentName)
methods. For more information, see Use multiple environments in ASP.NET Core.
public async Task Invoke(HttpContext context, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
// Configure middleware for Development
}
else
{
// Configure middleware for Staging/Production
}
var contentRootPath = env.ContentRootPath;
}
IHostApplicationLifetime
interface
Cancellation Token | Triggered when… |
---|---|
ApplicationStarted |
The host has fully started. |
ApplicationStopped |
The host is completing a graceful shutdown. All requests should be processed. ```Shutdown``` blocks until this event completes. |
ApplicationStopping |
The host is performing a graceful shutdown. Requests may still be processing. ```Shutdown``` blocks until this event completes. |
public class Startup
{
public void Configure(IApplicationBuilder app, IHostApplicationLifetime 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
}
}
public class MyClass
{
private readonly IHostApplicationLifetime _appLifetime;
public MyClass(IHostApplicationLifetime appLifetime)
{
_appLifetime = appLifetime;
}
public void Shutdown()
{
_appLifetime.StopApplication();
}
}
Scope validation
-
Scoped services aren't directly or indirectly resolved from the root service provider.
-
Scoped services aren't directly or indirectly injected into singletons.
WebHost.CreateDefaultBuilder(args)
.UseDefaultServiceProvider((context, options) => {
options.ValidateScopes = true;
})
Additional resources
-
Host ASP.NET Core on Windows with IIS
-
Host ASP.NET Core on Linux with Nginx
-
Host ASP.NET Core in a Windows Service