WebApplication and WebApplicationBuilder in Minimal API apps

WebApplication

The following code is generated by an ASP.NET Core template:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

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

app.Run();

The preceding code can be created via dotnet new web on the command line or selecting the Empty Web template in Visual Studio.

The following code creates a WebApplication (app) without explicitly creating a WebApplicationBuilder:

var app = WebApplication.Create(args);

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

app.Run();

WebApplication.Create initializes a new instance of the WebApplication class with preconfigured defaults.

WebApplication automatically adds the following middleware in Minimal API applications depending on certain conditions:

The following code is effectively what the automatic middleware being added to the app produces:

if (isDevelopment)
{
    app.UseDeveloperExceptionPage();
}

app.UseRouting();

if (isAuthenticationConfigured)
{
    app.UseAuthentication();
}

if (isAuthorizationConfigured)
{
    app.UseAuthorization();
}

// user middleware/endpoints
app.CustomMiddleware(...);
app.MapGet("/", () => "hello world");
// end user middleware/endpoints

app.UseEndpoints(e => {});

In some cases, the default middleware configuration isn't correct for the app and requires modification. For example, UseCors should be called before UseAuthentication and UseAuthorization. The app needs to call UseAuthentication and UseAuthorization if UseCors is called:

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();

If middleware should be run before route matching occurs, UseRouting should be called and the middleware should be placed before the call to UseRouting. UseEndpoints isn't required in this case as it is automatically added as described previously:

app.Use((context, next) =>
{
    return next(context);
});

app.UseRouting();

// other middleware and endpoints

When adding a terminal middleware:

  • The middleware must be added after UseEndpoints.
  • The app needs to call UseRouting and UseEndpoints so that the terminal middleware can be placed at the correct location.
app.UseRouting();

app.MapGet("/", () => "hello world");

app.UseEndpoints(e => {});

app.Run(context =>
{
    context.Response.StatusCode = 404;
    return Task.CompletedTask;
});

Terminal middleware is middleware that runs if no endpoint handles the request.

Working with ports

When a web app is created with Visual Studio or dotnet new, a Properties/launchSettings.json file is created that specifies the ports the app responds to. In the port setting samples that follow, running the app from Visual Studio returns an error dialog Unable to connect to web server 'AppName'. Visual Studio returns an error because it's expecting the port specified in Properties/launchSettings.json, but the app is using the port specified by app.Run("http://localhost:3000"). Run the following port changing samples from the command line.

The following sections set the port the app responds to.

var app = WebApplication.Create(args);

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

app.Run("http://localhost:3000");

In the preceding code, the app responds to port 3000.

Multiple ports

In the following code, the app responds to port 3000 and 4000.

var app = WebApplication.Create(args);

app.Urls.Add("http://localhost:3000");
app.Urls.Add("http://localhost:4000");

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

app.Run();

Set the port from the command line

The following command makes the app respond to port 7777:

dotnet run --urls="https://localhost:7777"

If the Kestrel endpoint is also configured in the appsettings.json file, the appsettings.json file specified URL is used. For more information, see Kestrel endpoint configuration

Read the port from environment

The following code reads the port from the environment:

var app = WebApplication.Create(args);

var port = Environment.GetEnvironmentVariable("PORT") ?? "3000";

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

app.Run($"http://localhost:{port}");

The preferred way to set the port from the environment is to use the ASPNETCORE_URLS environment variable, which is shown in the following section.

Set the ports via the ASPNETCORE_URLS environment variable

The ASPNETCORE_URLS environment variable is available to set the port:

ASPNETCORE_URLS=http://localhost:3000

ASPNETCORE_URLS supports multiple URLs:

ASPNETCORE_URLS=http://localhost:3000;https://localhost:5000

For more information using the environment, see Use multiple environments in ASP.NET Core

Listen on all interfaces

The following samples demonstrate listening on all interfaces

http://*:3000

var app = WebApplication.Create(args);

app.Urls.Add("http://*:3000");

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

app.Run();

http://+:3000

var app = WebApplication.Create(args);

app.Urls.Add("http://+:3000");

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

app.Run();

http://0.0.0.0:3000

var app = WebApplication.Create(args);

app.Urls.Add("http://0.0.0.0:3000");

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

app.Run();

Listen on all interfaces using ASPNETCORE_URLS

The preceding samples can use ASPNETCORE_URLS

ASPNETCORE_URLS=http://*:3000;https://+:5000;http://0.0.0.0:5005

Specify HTTPS with development certificate

var app = WebApplication.Create(args);

app.Urls.Add("https://localhost:3000");

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

app.Run();

For more information on the development certificate, see Trust the ASP.NET Core HTTPS development certificate on Windows and macOS.

Specify HTTPS using a custom certificate

The following sections show how to specify the custom certificate using the appsettings.json file and via configuration.

Specify the custom certificate with appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "Certificates": {
      "Default": {
        "Path": "cert.pem",
        "KeyPath": "key.pem"
      }
    }
  }
}

Specify the custom certificate via configuration

var builder = WebApplication.CreateBuilder(args);

// Configure the cert and the key
builder.Configuration["Kestrel:Certificates:Default:Path"] = "cert.pem";
builder.Configuration["Kestrel:Certificates:Default:KeyPath"] = "key.pem";

var app = builder.Build();

app.Urls.Add("https://localhost:3000");

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

app.Run();

Use the certificate APIs

using System.Security.Cryptography.X509Certificates;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    options.ConfigureHttpsDefaults(httpsOptions =>
    {
        var certPath = Path.Combine(builder.Environment.ContentRootPath, "cert.pem");
        var keyPath = Path.Combine(builder.Environment.ContentRootPath, "key.pem");

        httpsOptions.ServerCertificate = X509Certificate2.CreateFromPemFile(certPath, 
                                         keyPath);
    });
});

var app = builder.Build();

app.Urls.Add("https://localhost:3000");

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

app.Run();

Configuration

The following code reads from the configuration system:

var app = WebApplication.Create(args);

var message = app.Configuration["HelloKey"] ?? "Config failed!";

app.MapGet("/", () => message);

app.Run();

For more information, see Configuration in ASP.NET Core

Logging

The following code writes a message to the log on application startup:

var app = WebApplication.Create(args);

app.Logger.LogInformation("The app started");

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

app.Run();

For more information, see Logging in .NET Core and ASP.NET Core

Access the Dependency Injection (DI) container

The following code shows how to get services from the DI container during application startup:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddScoped<SampleService>();

var app = builder.Build();

app.MapControllers();

using (var scope = app.Services.CreateScope())
{
    var sampleService = scope.ServiceProvider.GetRequiredService<SampleService>();
    sampleService.DoSomething();
}

app.Run();

For more information, see Dependency injection in ASP.NET Core.

WebApplicationBuilder

This section contains sample code using WebApplicationBuilder.

Change the content root, application name, and environment

The following code sets the content root, application name, and environment:

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    ApplicationName = typeof(Program).Assembly.FullName,
    ContentRootPath = Directory.GetCurrentDirectory(),
    EnvironmentName = Environments.Staging,
    WebRootPath = "customwwwroot"
});

Console.WriteLine($"Application Name: {builder.Environment.ApplicationName}");
Console.WriteLine($"Environment Name: {builder.Environment.EnvironmentName}");
Console.WriteLine($"ContentRoot Path: {builder.Environment.ContentRootPath}");
Console.WriteLine($"WebRootPath: {builder.Environment.WebRootPath}");

var app = builder.Build();

WebApplication.CreateBuilder initializes a new instance of the WebApplicationBuilder class with preconfigured defaults.

For more information, see ASP.NET Core fundamentals overview

Change the content root, app name, and environment by environment variables or command line

The following table shows the environment variable and command-line argument used to change the content root, app name, and environment:

feature Environment variable Command-line argument
Application name ASPNETCORE_APPLICATIONNAME --applicationName
Environment name ASPNETCORE_ENVIRONMENT --environment
Content root ASPNETCORE_CONTENTROOT --contentRoot

Add configuration providers

The following sample adds the INI configuration provider:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddIniFile("appsettings.ini");

var app = builder.Build();

For detailed information, see File configuration providers in Configuration in ASP.NET Core.

Read configuration

By default the WebApplicationBuilder reads configuration from multiple sources, including:

  • appSettings.json and appSettings.{environment}.json
  • Environment variables
  • The command line

The following code reads HelloKey from configuration and displays the value at the / endpoint. If the configuration value is null, "Hello" is assigned to message:

var builder = WebApplication.CreateBuilder(args);

var message = builder.Configuration["HelloKey"] ?? "Hello";

var app = builder.Build();

app.MapGet("/", () => message);

app.Run();

For a complete list of configuration sources read, see Default configuration in Configuration in ASP.NET Core

Add logging providers

var builder = WebApplication.CreateBuilder(args);

// Configure JSON logging to the console.
builder.Logging.AddJsonConsole();

var app = builder.Build();

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

app.Run();

Add services

var builder = WebApplication.CreateBuilder(args);

// Add the memory cache services.
builder.Services.AddMemoryCache();

// Add a custom scoped service.
builder.Services.AddScoped<ITodoRepository, TodoRepository>();
var app = builder.Build();

Customize the IHostBuilder

Existing extension methods on IHostBuilder can be accessed using the Host property:

var builder = WebApplication.CreateBuilder(args);

// Wait 30 seconds for graceful shutdown.
builder.Host.ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));

var app = builder.Build();

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

app.Run();

Customize the IWebHostBuilder

Extension methods on IWebHostBuilder can be accessed using the WebApplicationBuilder.WebHost property.

var builder = WebApplication.CreateBuilder(args);

// Change the HTTP server implemenation to be HTTP.sys based
builder.WebHost.UseHttpSys();

var app = builder.Build();

app.MapGet("/", () => "Hello HTTP.sys");

app.Run();

Change the web root

By default, the web root is relative to the content root in the wwwroot folder. Web root is where the static files middleware looks for static files. Web root can be changed with WebHostOptions, the command line, or with the UseWebRoot method:

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    // Look for static files in webroot
    WebRootPath = "webroot"
});

var app = builder.Build();

app.Run();

Custom dependency injection (DI) container

The following example uses Autofac:

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// Register services directly with Autofac here. Don't
// call builder.Populate(), that happens in AutofacServiceProviderFactory.
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new MyApplicationModule()));

var app = builder.Build();

Add Middleware

Any existing ASP.NET Core middleware can be configured on the WebApplication:

var app = WebApplication.Create(args);

// Setup the file server to serve static files.
app.UseFileServer();

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

app.Run();

For more information, see ASP.NET Core Middleware

Developer exception page

WebApplication.CreateBuilder initializes a new instance of the WebApplicationBuilder class with preconfigured defaults. The developer exception page is enabled in the preconfigured defaults. When the following code is run in the development environment, navigating to / renders a friendly page that shows the exception.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () =>
{
    throw new InvalidOperationException("Oops, the '/' route has thrown an exception.");
});

app.Run();

WebApplication

The following code is generated by an ASP.NET Core template:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

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

app.Run();

The preceding code can be created via dotnet new web on the command line or selecting the Empty Web template in Visual Studio.

The following code creates a WebApplication (app) without explicitly creating a WebApplicationBuilder:

var app = WebApplication.Create(args);

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

app.Run();

WebApplication.Create initializes a new instance of the WebApplication class with preconfigured defaults.

WebApplication automatically adds the following middleware in Minimal API applications depending on certain conditions:

The following code is effectively what the automatic middleware being added to the app produces:

if (isDevelopment)
{
    app.UseDeveloperExceptionPage();
}

app.UseRouting();

if (isAuthenticationConfigured)
{
    app.UseAuthentication();
}

if (isAuthorizationConfigured)
{
    app.UseAuthorization();
}

// user middleware/endpoints
app.CustomMiddleware(...);
app.MapGet("/", () => "hello world");
// end user middleware/endpoints

app.UseEndpoints(e => {});

In some cases, the default middleware configuration isn't correct for the app and requires modification. For example, UseCors should be called before UseAuthentication and UseAuthorization. The app needs to call UseAuthentication and UseAuthorization if UseCors is called:

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();

If middleware should be run before route matching occurs, UseRouting should be called and the middleware should be placed before the call to UseRouting. UseEndpoints isn't required in this case as it is automatically added as described previously:

app.Use((context, next) =>
{
    return next(context);
});

app.UseRouting();

// other middleware and endpoints

When adding a terminal middleware:

  • The middleware must be added after UseEndpoints.
  • The app needs to call UseRouting and UseEndpoints so that the terminal middleware can be placed at the correct location.
app.UseRouting();

app.MapGet("/", () => "hello world");

app.UseEndpoints(e => {});

app.Run(context =>
{
    context.Response.StatusCode = 404;
    return Task.CompletedTask;
});

Terminal middleware is middleware that runs if no endpoint handles the request.

Working with ports

When a web app is created with Visual Studio or dotnet new, a Properties/launchSettings.json file is created that specifies the ports the app responds to. In the port setting samples that follow, running the app from Visual Studio returns an error dialog Unable to connect to web server 'AppName'. Visual Studio returns an error because it's expecting the port specified in Properties/launchSettings.json, but the app is using the port specified by app.Run("http://localhost:3000"). Run the following port changing samples from the command line.

The following sections set the port the app responds to.

var app = WebApplication.Create(args);

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

app.Run("http://localhost:3000");

In the preceding code, the app responds to port 3000.

Multiple ports

In the following code, the app responds to port 3000 and 4000.

var app = WebApplication.Create(args);

app.Urls.Add("http://localhost:3000");
app.Urls.Add("http://localhost:4000");

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

app.Run();

Set the port from the command line

The following command makes the app respond to port 7777:

dotnet run --urls="https://localhost:7777"

If the Kestrel endpoint is also configured in the appsettings.json file, the appsettings.json file specified URL is used. For more information, see Kestrel endpoint configuration

Read the port from environment

The following code reads the port from the environment:

var app = WebApplication.Create(args);

var port = Environment.GetEnvironmentVariable("PORT") ?? "3000";

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

app.Run($"http://localhost:{port}");

The preferred way to set the port from the environment is to use the ASPNETCORE_URLS environment variable, which is shown in the following section.

Set the ports via the ASPNETCORE_URLS environment variable

The ASPNETCORE_URLS environment variable is available to set the port:

ASPNETCORE_URLS=http://localhost:3000

ASPNETCORE_URLS supports multiple URLs:

ASPNETCORE_URLS=http://localhost:3000;https://localhost:5000

Listen on all interfaces

The following samples demonstrate listening on all interfaces

http://*:3000

var app = WebApplication.Create(args);

app.Urls.Add("http://*:3000");

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

app.Run();

http://+:3000

var app = WebApplication.Create(args);

app.Urls.Add("http://+:3000");

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

app.Run();

http://0.0.0.0:3000

var app = WebApplication.Create(args);

app.Urls.Add("http://0.0.0.0:3000");

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

app.Run();

Listen on all interfaces using ASPNETCORE_URLS

The preceding samples can use ASPNETCORE_URLS

ASPNETCORE_URLS=http://*:3000;https://+:5000;http://0.0.0.0:5005

Listen on all interfaces using ASPNETCORE_HTTPS_PORTS

The preceding samples can use ASPNETCORE_HTTPS_PORTS and ASPNETCORE_HTTP_PORTS.

ASPNETCORE_HTTP_PORTS=3000;5005
ASPNETCORE_HTTPS_PORTS=5000

For more information, see Configure endpoints for the ASP.NET Core Kestrel web server

Specify HTTPS with development certificate

var app = WebApplication.Create(args);

app.Urls.Add("https://localhost:3000");

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

app.Run();

For more information on the development certificate, see Trust the ASP.NET Core HTTPS development certificate on Windows and macOS.

Specify HTTPS using a custom certificate

The following sections show how to specify the custom certificate using the appsettings.json file and via configuration.

Specify the custom certificate with appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "Certificates": {
      "Default": {
        "Path": "cert.pem",
        "KeyPath": "key.pem"
      }
    }
  }
}

Specify the custom certificate via configuration

var builder = WebApplication.CreateBuilder(args);

// Configure the cert and the key
builder.Configuration["Kestrel:Certificates:Default:Path"] = "cert.pem";
builder.Configuration["Kestrel:Certificates:Default:KeyPath"] = "key.pem";

var app = builder.Build();

app.Urls.Add("https://localhost:3000");

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

app.Run();

Use the certificate APIs

using System.Security.Cryptography.X509Certificates;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(options =>
{
    options.ConfigureHttpsDefaults(httpsOptions =>
    {
        var certPath = Path.Combine(builder.Environment.ContentRootPath, "cert.pem");
        var keyPath = Path.Combine(builder.Environment.ContentRootPath, "key.pem");

        httpsOptions.ServerCertificate = X509Certificate2.CreateFromPemFile(certPath, 
                                         keyPath);
    });
});

var app = builder.Build();

app.Urls.Add("https://localhost:3000");

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

app.Run();

Read the environment

var app = WebApplication.Create(args);

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/oops");
}

app.MapGet("/", () => "Hello World");
app.MapGet("/oops", () => "Oops! An error happened.");

app.Run();

For more information using the environment, see Use multiple environments in ASP.NET Core

Configuration

The following code reads from the configuration system:

var app = WebApplication.Create(args);

var message = app.Configuration["HelloKey"] ?? "Config failed!";

app.MapGet("/", () => message);

app.Run();

For more information, see Configuration in ASP.NET Core

Logging

The following code writes a message to the log on application startup:

var app = WebApplication.Create(args);

app.Logger.LogInformation("The app started");

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

app.Run();

For more information, see Logging in .NET Core and ASP.NET Core

Access the Dependency Injection (DI) container

The following code shows how to get services from the DI container during application startup:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddScoped<SampleService>();

var app = builder.Build();

app.MapControllers();

using (var scope = app.Services.CreateScope())
{
    var sampleService = scope.ServiceProvider.GetRequiredService<SampleService>();
    sampleService.DoSomething();
}

app.Run();

The following code shows how to access keys from the DI container using the [FromKeyedServices] attribute:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");

var app = builder.Build();

app.MapGet("/big", ([FromKeyedServices("big")] ICache bigCache) => bigCache.Get("date"));

app.MapGet("/small", ([FromKeyedServices("small")] ICache smallCache) => smallCache.Get("date"));

app.Run();

public interface ICache
{
    object Get(string key);
}
public class BigCache : ICache
{
    public object Get(string key) => $"Resolving {key} from big cache.";
}

public class SmallCache : ICache
{
    public object Get(string key) => $"Resolving {key} from small cache.";
}

For more information on DI, see Dependency injection in ASP.NET Core.

WebApplicationBuilder

This section contains sample code using WebApplicationBuilder.

Change the content root, application name, and environment

The following code sets the content root, application name, and environment:

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    ApplicationName = typeof(Program).Assembly.FullName,
    ContentRootPath = Directory.GetCurrentDirectory(),
    EnvironmentName = Environments.Staging,
    WebRootPath = "customwwwroot"
});

Console.WriteLine($"Application Name: {builder.Environment.ApplicationName}");
Console.WriteLine($"Environment Name: {builder.Environment.EnvironmentName}");
Console.WriteLine($"ContentRoot Path: {builder.Environment.ContentRootPath}");
Console.WriteLine($"WebRootPath: {builder.Environment.WebRootPath}");

var app = builder.Build();

WebApplication.CreateBuilder initializes a new instance of the WebApplicationBuilder class with preconfigured defaults.

For more information, see ASP.NET Core fundamentals overview

Change the content root, app name, and environment by using environment variables or command line

The following table shows the environment variable and command-line argument used to change the content root, app name, and environment:

feature Environment variable Command-line argument
Application name ASPNETCORE_APPLICATIONNAME --applicationName
Environment name ASPNETCORE_ENVIRONMENT --environment
Content root ASPNETCORE_CONTENTROOT --contentRoot

Add configuration providers

The following sample adds the INI configuration provider:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddIniFile("appsettings.ini");

var app = builder.Build();

For detailed information, see File configuration providers in Configuration in ASP.NET Core.

Read configuration

By default the WebApplicationBuilder reads configuration from multiple sources, including:

  • appSettings.json and appSettings.{environment}.json
  • Environment variables
  • The command line

For a complete list of configuration sources read, see Default configuration in Configuration in ASP.NET Core.

The following code reads HelloKey from configuration and displays the value at the / endpoint. If the configuration value is null, "Hello" is assigned to message:

var builder = WebApplication.CreateBuilder(args);

var message = builder.Configuration["HelloKey"] ?? "Hello";

var app = builder.Build();

app.MapGet("/", () => message);

app.Run();

Read the environment

var builder = WebApplication.CreateBuilder(args);

if (builder.Environment.IsDevelopment())
{
    Console.WriteLine($"Running in development.");
}

var app = builder.Build();

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

app.Run();

Add logging providers

var builder = WebApplication.CreateBuilder(args);

// Configure JSON logging to the console.
builder.Logging.AddJsonConsole();

var app = builder.Build();

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

app.Run();

Add services

var builder = WebApplication.CreateBuilder(args);

// Add the memory cache services.
builder.Services.AddMemoryCache();

// Add a custom scoped service.
builder.Services.AddScoped<ITodoRepository, TodoRepository>();
var app = builder.Build();

Customize the IHostBuilder

Existing extension methods on IHostBuilder can be accessed using the Host property:

var builder = WebApplication.CreateBuilder(args);

// Wait 30 seconds for graceful shutdown.
builder.Host.ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));

var app = builder.Build();

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

app.Run();

Customize the IWebHostBuilder

Extension methods on IWebHostBuilder can be accessed using the WebApplicationBuilder.WebHost property.

var builder = WebApplication.CreateBuilder(args);

// Change the HTTP server implemenation to be HTTP.sys based
builder.WebHost.UseHttpSys();

var app = builder.Build();

app.MapGet("/", () => "Hello HTTP.sys");

app.Run();

Change the web root

By default, the web root is relative to the content root in the wwwroot folder. Web root is where the static files middleware looks for static files. Web root can be changed with WebHostOptions, the command line, or with the UseWebRoot method:

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    // Look for static files in webroot
    WebRootPath = "webroot"
});

var app = builder.Build();

app.Run();

Custom dependency injection (DI) container

The following example uses Autofac:

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// Register services directly with Autofac here. Don't
// call builder.Populate(), that happens in AutofacServiceProviderFactory.
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new MyApplicationModule()));

var app = builder.Build();

Add Middleware

Any existing ASP.NET Core middleware can be configured on the WebApplication:

var app = WebApplication.Create(args);

// Setup the file server to serve static files.
app.UseFileServer();

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

app.Run();

For more information, see ASP.NET Core Middleware

Developer exception page

WebApplication.CreateBuilder initializes a new instance of the WebApplicationBuilder class with preconfigured defaults. The developer exception page is enabled in the preconfigured defaults. When the following code is run in the development environment, navigating to / renders a friendly page that shows the exception.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () =>
{
    throw new InvalidOperationException("Oops, the '/' route has thrown an exception.");
});

app.Run();