European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET Core 9.0 Hosting - HostForLIFE :: Using Bootstrap 5 Themes in ASP.NET 8

clock January 21, 2025 06:57 by author Peter

Abstract: In an ASP.NET8 MVC application, we demonstrate how to set up the use of numerous Bootstrap 5 themes. There are a lot of free Bootstrap 5 themes online that can improve the appearance of web apps.

1. The requirement for a more polished user interface
By default, the ASP.NET8 MVC project uses the Bootstrap 5 CSS UI framework. However, for some reason, the Bank application I was working on does not look very good with the default Bootstrap 5 color scheme. I therefore had to find some better Bootstrap 5 themes.

1.1. Free Bootstrap 5 themes
There are many free Bootstrap themes on the Internet. I liked the site Bootswatch [1]. Themes there are FREE, with an MIT license. I decided to use those free themes for my project. I realized, theoretically, I can even make the admin choose the theme for the app from several themes I offer preinstalled. So, I decided to make a proof-of-concept application.

2. Installing multiple Bootstrap 5 Themes
2.1. Configuration in appsetting.json

I decided to enable the web application admin to select the theme he/she prefers using the configuration option in appsettings.json.

2.2. Installing multiple themes
I downloaded several themes I liked and installed in the app.

2.3. Passing theme number to the Partial view
I defined my model and passed the info to _Layout.cshtml.
From there, I passed the info to the partial view _LoadingLayoutJsAndCss.cshtml.

In that partial view _LoadingLayoutJsAndCss.cshtml, I decide which Bootstrap theme to load based on the number configured in appsettings.json.

3. Final result
I will just show here what some themes look like in my prototype ASP.NET8 app. Please note that Theme 0 is the default Bootstrap 5 theme. It is pretty impressive how a good theme can change an app's look. The problem is that Bootstrap Theme sometimes changes not just colors but border thickness, button shape (rounded, square, etc), spacing between elements, etc. Theoretically, you need to test every dialog/form for each Bootstrap Theme you offer to users.

 

 

 

4. Concerns and Conclusion
The problem is that each theme not only changes colors but also button sizes and spacing, so theoretically, one would need to test “every form for every theme” to make sure it renders properly before delivering the product. I needed to do some work on CSS to support Themes. I needed to make sure components CSS like Breadcrumb and DataTables inherit colors from the theme. The problem is if they have color definitions in their own CSS, they will not follow the theme. You might need to do some work there.

If the project team/QA team wants to focus on only one theme, you can use the HARDCODE theme number in the release build and disable that config option. Just, I think the developers-team would need to do development in the Bootstrap default theme (0), to make sure they do not fall for some bug in the theme itself. Those themes themselves can have bugs/issues. Still, it is amazing how many quality free resources one can find for the Bootstrap UI framework.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Implement JWT Token in Net Core Api

clock January 16, 2025 07:06 by author Peter

The ASP.NET Core API's JWT (JSON Web Token) authentication provides a safe and effective method for managing user authorization and authentication. A detailed guide to configuring JWT authentication in an ASP.NET Core Web API can be found here.

Install Required NuGet Packages

Configure JWT Authentication
Update Program.cs to configure JWT authentication in the service section and middleware section.

builder.Services.AddAuthentication(opt =>
{
    opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(opt =>
{   // for development only
    opt.RequireHttpsMetadata = false;
    opt.SaveToken = true;
    opt.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["JWT:SecretKey"])),
        ValidateIssuer = true,
        ValidIssuer = builder.Configuration["JWT:Issuer"],
        ValidateAudience = true,
        ValidAudience = builder.Configuration["JWT:Audience"]
    };
});

builder.Services.AddAuthorization();

var app = builder.Build();

// Use authentication and authorization
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();


This configuration sets up the application to authenticate incoming requests using the JWT tokens and validate them based on certain parameters.

Generate the JWT Tokens
public string GenerateJwtToken(string userName, string name, string role)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(_configuration["JWT:SecretKey"]);

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[]
        {
            new Claim(ClaimTypes.Name, userName),
            new Claim(ClaimTypes.GivenName, name),
            new Claim(ClaimTypes.Role, role)
        }),
        IssuedAt = DateTime.UtcNow,
        Issuer = _configuration["JWT:Issuer"],
        Audience = _configuration["JWT:Audience"],
        Expires = DateTime.UtcNow.AddMinutes(30), // can change exprires time
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    var userToken = tokenHandler.WriteToken(token);

    return userToken;
}

Authenticate Users And Issue The JWT Tokens
[HttpPost("login")]
public IActionResult Login(LoginModel model)
{
    // Authenticate user
    var user = _userService.Authenticate(model.Username, model.Password);

    if (user == null)
        return Unauthorized();

    // Generate JWT token
    var token = _authenticationService.GenerateJwtToken(
        user.userName,
        user.Name,
        user.Role
    );

    return Ok(new { token });
}


Secure Your API Endpoints
Add the [Authorize] attribute to protect API endpoints. Example.
[ApiController]
[Route("api/[controller]")]
public class ProtectedController : ControllerBase
{
    [HttpGet]
    [Authorize]
    public IActionResult GetSecureData()
    {
        return Ok(new { Message = "This is a secure endpoint." });
    }
}


Test Your .NET JWT Authentication
Use a tool like Postman or cURL to test the endpoints.
First, call the /api/auth/login endpoint with valid credentials to get a token.
Use the token in the Authorization header of subsequent requests to protected endpoints:
Authorization: Bearer <your-jwt-token>

JWT token part
A JWT (JSON Web Token) consists of three parts, separated by dots (.): Header, Payload, and Signature. Here's a breakdown of these parts.

Header
The header typically consists of two fields.

  • alg: The signing algorithm used (e.g., HS256 for HMAC-SHA256).
  • typ: The type of the token, usually JWT.

{
"alg": "HS256",
"typ": "JWT"
}


Payload
The payload contains the claims. Claims are statements about the user or additional data. There are three types of claims.

  • Registered claims: Predefined claims like iss (issuer), exp (expiration), sub (subject), and aud (audience).
  • Public claims: Custom claims defined for specific use cases.
  • Private claims: Claims shared between parties that agree on them.

{
"sub": "1234567890",
"name": "peter",
"role": "Admin",
"iat": 1672545600,
"exp": 1672549200
}


Signature

The signature is used to verify the authenticity of the token and ensure that it hasn’t been tampered with.

The signature is created by,

Taking the encoded header and payload.

Concatenating them with a dot (.).
Hashing the result using the specified algorithm and a secret key.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret_key
)


Final Token format

The JWT token is the concatenation of these three parts.
<base64UrlEncodedHeader>.<base64UrlEncodedPayload>.<base64UrlEncodedSignature>

Example
JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwicm9sZSI6IkFkbWluIiwiaWF0IjoxNjcyNTQ1NjAwLCJleHAiOjE2NzI1NDkyMDB9.DjKU_JB_b9PxwjU_x5U3wwtrLX7ZnZZ0mKXfTi5YYCU

Conclusion
Ultimately, we can say that authorization and authentication in.NET Core are essential to the safety and security of your application, and that using JWT authentication in.NET Core offers a reliable and secure way to authenticate users and safeguard web application resources. Data integrity and confidentiality are prioritized while.NET Core applications obtain scalability, flexibility, and interoperability with the inclusion of JWT authentication. This ensures a smooth user experience. Adopting.NET JWT authentication in.NET Core is still a crucial tactic for protecting private data and bolstering the integrity of contemporary web apps as technology advances.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: Mastering [Produces("application/json")] in ASP.NET Core

clock January 10, 2025 06:32 by author Peter

If you're using ASP.NET Core to create reliable APIs, you've probably come across situations where answer format consistency is essential. It [Produces("application/json")] is useful in this situation. Let's examine its operation and the reasons it is revolutionary.

What does [Produces("application/json")] do?
It tells your API to always respond with JSON, regardless of the client’s request headers. No surprises just clean, predictable JSON responses every time.

Where and How to use It?
You can apply it at the controller or action level.
[Produces("application/json")]
[ApiController]
[Route("api/[controller]")]
public class ExampleController : ControllerBase
{
    [HttpGet]
    public IActionResult GetData()
    {
        var data = new { Message = "Hello, JSON!" };
        return Ok(data);
    }
}


What happens here?
Even if the client requests XML, your API says.
“Nope, JSON it is!”

Why use it?

  • Consistency: Ensures your API always speaks the same "language" (JSON).
  • Simplicity: Reduces unexpected behaviour caused by content negotiation.
  • Control: Guarantees the response format, no matter what the client expects.

Pro Tip
Want to support multiple formats (e.g., XML and JSON)? Use [Produces] with a list of content types.
[Produces("application/json", "application/xml")]

When to use It?

  • Use [Produces("application/json")] when.
  • Your API should always output JSON.
  • You want strict control over response formatting.
  • You’re building APIs for front-end frameworks or third-party clients that expect JSON.

In today’s API-driven world, it [Produces("application/json")] is your ally for predictable, reliable, and developer-friendly APIs. Start using it today to level up your API game.



European ASP.NET Core 9.0 Hosting - HostForLIFE :: What Does Minimal API's MapGroup Mean?

clock January 6, 2025 07:58 by author Peter

A lightweight method for creating HTTP APIs is offered by.NET Core's minimal APIs. They were first introduced in.NET 6 and improved in subsequent iterations, enabling you to process HTTP requests and construct routes with less boilerplate. MapGroup is a potent component of Minimal APIs that facilitates effective route organization and structuring.

In this article, we’ll explore.What is MapGroup?

  • Benefits of using MapGroup.
  • Pros and cons.
  • When and why to use MapGroup.
  • A practical example to showcase its use.

What is MapGroup?
MapGroup is a feature in Minimal APIs that allows you to group related endpoints together under a common route prefix and configuration. It helps in organizing endpoints logically, making your codebase more readable and maintainable.

Mapping ground in a Minimal API refers to the process of defining routes and handling requests in a streamlined manner, leveraging the simplicity of .NET's Minimal APIs. This approach allows developers to create lightweight web applications with less boilerplate code, enhancing productivity.
Example: Traditional vs. MapGroup

Without MapGroup
var app = builder.Build();

app.MapGet("/users", () => "List of users");
app.MapGet("/users/{id}", (int id) => $"User details for {id}");
app.MapPost("/users", () => "Create a new user");

app.Run();


With MapGroup

var app = builder.Build();
var usersGroup = app.MapGroup("/users");

usersGroup.MapGet("/", () => "List of users");
usersGroup.MapGet("/{id}", (int id) => $"User details for {id}");
usersGroup.MapPost("/", () => "Create a new user");

app.Run();


By using MapGroup, all endpoints under /users are grouped together, improving organization and scalability.

Key Features of MapGroup

  • Route Prefixing: Automatically applies a common prefix to all endpoints within the group.
  • Shared Middleware: Apply middleware like authentication or logging to all endpoints in a group.
  • Logical Organization: Separate concerns by grouping related endpoints (e.g., /users, /orders).

Practical Example
Here’s a complete example of using MapGroup with additional configurations.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Users Group
var usersGroup = app.MapGroup("/users")
                    .RequireAuthorization()
                    .WithOpenApi();

usersGroup.MapGet("/", () => "List of users");
usersGroup.MapGet("/{id:int}", (int id) => $"User details for {id}");
usersGroup.MapPost("/", () => "Create a new user");

// Orders Group
var ordersGroup = app.MapGroup("/orders")
                     .AddEndpointFilter(async (context, next) =>
                     {
                         // Example filter logic
                         Console.WriteLine("Processing order request");
                         return await next(context);
                     });

ordersGroup.MapGet("/", () => "List of orders");
ordersGroup.MapPost("/", () => "Create a new order");

app.Run();

Benefits of MapGroup

  • Clean Code Organization: MapGroup enables logical grouping of related routes, reducing clutter in your Program.cs file.
  • Shared Middleware: Apply middleware like authorization, logging, or custom filters to an entire group instead of individual endpoints.
  • Route Consistency: It automatically adds a common prefix to all routes, avoiding duplication and potential errors.
  • Scalability: As your API grows, you can easily manage and extend endpoint groups without impacting unrelated routes.
  • Enhanced Maintainability: Improves the readability of your codebase, making it easier for teams to collaborate and manage.
  • Simplicity: Minimal APIs reduce the complexity of setting up a web server.
  • Performance: They are lightweight, leading to faster response times.
  • Flexibility: Easy to modify and extend as requirements change.

Pros and Cons

Pros

  • Simplifies route definitions.
  • Reduces code duplication for common configurations.
  • Works seamlessly with middleware and filters.
  • Enhances readability and maintainability.
  • Less code to manage.
  • Quick to set up and deploy.
  • Ideal for microservices and small applications.

Cons

  • Only available in the Minimal API approach.
  • Teams accustomed to traditional controllers may face a learning curve.
  • Misconfiguration in a group could affect multiple endpoints.
  • Limited features compared to full-fledged frameworks.
  • May not be suitable for large applications requiring extensive routing and middleware.

When and Why to Use MapGroup?
When to Use
Consider using Minimal APIs when developing small to medium-sized applications, microservices, or when rapid prototyping is needed. They are particularly beneficial when you want to focus on specific functionalities without the overhead of a traditional MVC framework.

You’re building an API with Minimal APIs and need to manage multiple related routes.
You want to apply common configurations, such as authentication, to a set of routes.
Your project requires scalability, with endpoints logically organized by feature or resource.

Why Use

  • To keep your Program.cs file manageable as your API grows.
  • To improve the readability and structure of your Minimal API.
  • To enforce consistency in route prefixes and middleware usage.

mapping ground in Minimal API is a powerful approach for developers looking to create efficient and straightforward web applications in .NET.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in