Blog

Filter posts by Category Or Tag of the Blog section!

Web application builder and generic host in asp.net core

Monday, 07 November 2022

A web application builder is a feature built into ASP.NET Core that simplifies the process of creating a web application by providing a set of pre-built templates and components that you can use to build your application. The most common web application builder in ASP.NET Core is the MVC (Model-View-Controller) framework which probably is familiar to you if you are a .net developer. It provides a structured way to build web applications by separating the application logic into three distinct components: the model, the view, and the controller. Other web application builders in ASP.NET Core include Razor Pages and Blazor, which offer alternative approaches to building web applications.

On the other hand, a generic host is a low-level hosting API that provides a more flexible way to build web applications in ASP.NET Core. With a generic host, you have more control over the application's startup process and can use a wider variety of components and middleware to build your application. A generic host can be used to host web applications, but it can also be used to host other types of applications, such as background services such as worker or console applications.

Both web application builders and generic hosts have their own advantages and disadvantages, and the choice between them depends on the specific needs of your application the solution should be chosen exactly based on the problem. Web application builders are generally easier to use and provide a more streamlined development experience, while generic hosts offer more flexibility and control over the application's behavior.


Such an example of using the web application builder approach to create a simple MVC web application in ASP.NET Core:

 

public class Startup

{

    public void ConfigureServices(IServiceCollection services)

    {

        services.AddControllersWithViews();

    }



    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    {

        if (env.IsDevelopment())

        {

            app.UseDeveloperExceptionPage();

        }

        else

        {

            app.UseExceptionHandler("/Home/Error");

        }



        app.UseStaticFiles();



        app.UseRouting();



        app.UseEndpoints(endpoints =>

        {

            endpoints.MapControllerRoute(

                name: "default",

                pattern: "{controller=Home}/{action=Index}/{id?}");

        });

    }

}

 

And in HomeController.cs:

 

public class HomeController : Controller

{

    public IActionResult Index()

    {

        return View();

    }

}

 

In this example, we use the AddControllersWithViews() method to register the MVC middleware, and then configure the application using the Configure() method. We use the UseStaticFiles() method to serve static files (such as CSS and JavaScript files and everything inside wwwroot folder), and the UseRouting() method to enable routing for incoming requests. Finally, we use the MapControllerRoute() method to define a default route for our application, which maps incoming requests to the Index() action of the HomeController by default.

In the HomeController, we define the Index() action, which returns a view that will be rendered by the MVC framework. In this example, the view is not defined, but it could be a Razor view that contains HTML markup and other dynamic content.

Remember that This is just a basic example of using the web application builder approach in ASP.NET Core. More complex applications might require additional middleware and configuration, but the general approach remains the same and in a production and complex application, you will have more configuration in your startup.cs such as middlewares, filters and etc.

The example below is a real-world application configuration in that I only renamed the names: 

 

public class Startup

{

    public void ConfigureServices(IServiceCollection services)

    {

        services.AddDbContext<MyDbContext>(options =>

            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));



        services.AddIdentity<ApplicationUser, IdentityRole>()

            .AddEntityFrameworkStores<MyDbContext>()

            .AddDefaultTokenProviders();



        services.AddAuthentication(options =>

        {

            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;

            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;

            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

        })

        .AddJwtBearer(options =>

        {

            options.RequireHttpsMetadata = false;

            options.SaveToken = true;

            options.TokenValidationParameters = new TokenValidationParameters

            {

                ValidateIssuerSigningKey = true,

                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Jwt:Key"])),

                ValidateIssuer = false,

                ValidateAudience = false,

                ClockSkew = TimeSpan.Zero

            };

        });



        services.AddAuthorization(options =>

        {

            options.AddPolicy("RequireAdministratorRole", policy =>

                policy.RequireRole("Administrator"));

        });



        services.AddControllers();

    }



    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MyDbContext dbContext)

    {

        if (env.IsDevelopment())

        {

            app.UseDeveloperExceptionPage();

        }



        app.UseHttpsRedirection();



        app.UseRouting();



        app.UseAuthentication();

        app.UseAuthorization();



        app.UseEndpoints(endpoints =>

        {

            endpoints.MapControllers();

        });



        dbContext.Database.Migrate();

    }

}



// In ValuesController.cs

[Authorize(Policy = "RequireAdministratorRole")]

[ApiController]

[Route("api/[controller]")]

public class ValuesController : ControllerBase

{

    [HttpGet]

    public IEnumerable<string> Get()

    {

        return new string[] { "value1", "value2" };

    }

}

 

In this example, I used the AddDbContext() method to register our database context, and the AddIdentity() method to register the Identity framework for user authentication and authorization. I also configured JWT (for authentication and authorization) policies using the AddAuthentication() and AddAuthorization() methods.

In the Configure() method, I enabled HTTPS redirection, routing, authentication, and authorization using the UseHttpsRedirection(), UseRouting(), UseAuthentication(), and UseAuthorization() methods, respectively. I then map our API controllers using the MapControllers() method of the UseEndpoints() method.

Finally, we define a sample API controller called ValuesController that requires authentication and the "RequireAdministratorRole" authorization policy. The Get() method returns an array of string values.

comments powered by Disqus