Startup.cs in ASP.NET Core

Startup.cs file in asp.net core application contain all configuration and hosting related information.

Startup class or Startup.cs file is generated as part of the default Asp.net Core template. Startup class is the entry point of application. It configures the request pipeline that handles all requests made to the application.

Startup.cs is used for configuration & Startup Class is mandatory in Asp.net Core application
What is Startup class in Asp.net Core?

Can we rename the startup class to some other name?
Yes, Finally this Startup.cs is used in Program class for hosting the application, So renaming this class will not make any difference.

Startup Class Constructor Dependency Injection

Here you can see how new instance of "IConfiguration" is being created, by setting up IConfiguration instance in startup constructor will allow us to access all configuration related information.

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

In Startup file you can see an example of dependency injection

startup.cs in asp.net core
ConfigureServices Method in Startup.cs

In ConfigureService method we can configure any service in that application, to do that all service to be added in IServiceCollection
For example you can see how below methods are added
services.AddMvc(); this was added by default
services.Configure<DbConnection>(Configuration.GetSection("DbConnectionConfig"));

public class Startup
{ // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
 services.Configure<DbConnection>(Configuration.GetSection("DbConnectionConfig"));
    }
}

In above example we are try to configure a DbConnectionConfig class we read information from appSetting.json class, so we want when service starts, all configuration information to be available in custom configuration class

Configure Method in Startup.cs

This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
DbConnectionString = string.Format("Server={0};Database={1};
User ID={2};Password={3};Trusted_Connection=False;
MultipleActiveResultSets=true;",
Configuration["DbConnectionConfig:ServerName"],
Configuration["DbConnectionConfig:DatabaseName"],
Configuration["DbConnectionConfig:UserName"],
Configuration["DbConnectionConfig:Password"]);
app.UseStaticFiles();
app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

How to keep startup.cs file clean

As we know, we have to write many different service configurations details in startup file, and the file will have so many different type of code and become dirty and difficult to manage.

Think of situation like, configuring JWT token in startup file, we have to write code like example below.

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHttpClient();
services.AddSingleton<IJwtService, JwtService>();
services.AddMvcCore(option=>
{
option.RespectBrowserAcceptHeader=true;
option.FormatterMappings.SetMediaTypeMappingForFormat(
"xml", MediaTypeHeaderValue.Parse("text/xml"));
option.FormatterMappings.SetMediaTypeMappingForFormat(
"json", MediaTypeHeaderValue.Parse("application/json"));
});
var _keySecret = config.GetValue<string>("Jwt:SigningKey");
var _securitykey = new SymmetricSecurityKey(
System.Text.Encoding.UTF8.GetBytes(_keySecret));
services.AddAuthentication(option =>
{ option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer("Bearer", jwtb => {
	    //jwtb.SaveToken = true;
	    //jwtb.RequireHttpsMetadata = false;
	    jwtb.TokenValidationParameters = new TokenValidationParameters
	    {
		    ValidateIssuerSigningKey = true,
		    IssuerSigningKey = _securitykey,
		    ValidateIssuer = true,
		    ValidIssuer = config.GetValue<string>("Jwt:ValidIssuer"),
		    ValidateAudience = true,
		    ValidAudiences = new string[] { config.GetValue<string>("Jwt:ValidAudiences") },
		    ValidateLifetime = true,
		    ClockSkew = System.TimeSpan.FromMinutes(4),
	    };
    });
	
}

Now look at the above code, we have just added two services, what will happen if you add fifteen services in startup file, the file will be difficult to read and really dirty, right?

Here is the solution; we should create an extension file for each service, especially when there are too many configuration details, then in startup.cs file we just need to write one line of code.

I have created a new file called “JWTAuthenticationExtension.cs” , and moved all jwt configuration details there.

namespace WebAPICore.Middleware
{
    public static class JWTAuthenticationExtension
    {        
        public static IServiceCollection AddJwtTokenAuthentication(this IServiceCollection services,
            IConfiguration config)
        {
            var _keySecret = config.GetValue<string>("Jwt:SigningKey");
            var _securitykey = new SymmetricSecurityKey(
            System.Text.Encoding.UTF8.GetBytes(_keySecret));
            services.AddAuthentication(option =>
            {   
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer("Bearer", jwtb => {
                //jwtb.SaveToken = true;
                //jwtb.RequireHttpsMetadata = false;
                jwtb.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = _securitykey,
                    ValidateIssuer = true,
                    ValidIssuer = config.GetValue<string>("Jwt:ValidIssuer"),
                    ValidateAudience = true,
                    ValidAudiences = new string[] { config.GetValue<string>("Jwt:ValidAudiences") },
                    ValidateLifetime = true,
                    ClockSkew = System.TimeSpan.FromMinutes(4),
                };
            });
            return services;
        }
    }
}

Now, in startup.cs file, we have to just add one line of code like services.AddJwtTokenAuthentication(Configuration);.

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHttpClient();
services.AddJwtTokenAuthentication(Configuration);
    }
}

Now, read the above startup.cs file, the file is so clean and easy to read.

Note, there will be no startup file when we create asp.net core application in Visual Studio 2022, here you can read about configuration changes in Visual Studio 2022 for .Net Core.

Asp.Net Core C# Examples | Join Asp.Net MVC Course