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 Hosting - HostForLIFE :: Minimal API Using .NET Core 6 Web API

clock October 24, 2022 09:41 by author Peter

We will discuss minimal APIs in .NET Core 6, their purpose, and step-by-step implementation.

Introduction
    Minimal APIs are used to create HTTP APIs with minimum dependencies and configuration.
    Mostly it is used in microservices that have fewer files and functionality within a single file
    But there are a few things that are not supported in minimal APIs like action filters, and built-in validation, also, a few more that are still in progress and will get in the future by .NET Team.

Minimal APIs Implementation using .NET Core 6
Step 1
Create a new .NET Core Web API

Step 2
Configure your project

Step 4
Install the following NuGet packages

Project structure

Step 5
Create a Product class inside the entities folder
namespace MinimalAPIsDemo.Entities
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public int ProductPrice { get; set; }
        public int ProductStock { get; set; }
    }
}

Step 6
Next, create DbContextClass inside the Data folder
using Microsoft.EntityFrameworkCore;
using MinimalAPIsDemo.Entities;

namespace MinimalAPIsDemo.Data
{
    public class DbContextClass : DbContext
    {
        protected readonly IConfiguration Configuration;

        public DbContextClass(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
        }

        public DbSet<Product> Product { get; set; }
    }
}


Step 7
Register the Db Context service in the DI container inside the Program class which is the entry point of our application
// Add services to the container.
builder.Services.AddDbContext<DbContextClass>();

Step 8
Add database connection string inside the app settings file
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=DESKTOP;Initial Catalog=MinimalAPIDemo;User Id=sa;Password=database;"
  }
}


Step 9
Later on, add different API endpoints inside the Program class with the help of Map and specified routing pattern as I showed below
using Microsoft.EntityFrameworkCore;
using MinimalAPIsDemo.Data;
using MinimalAPIsDemo.Entities;

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext<DbContextClass>();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

//get the list of product
app.MapGet("/productlist", async (DbContextClass dbContext) =>
{
    var products = await dbContext.Product.ToListAsync();
    if (products == null)
    {
        return Results.NoContent();
    }
    return Results.Ok(products);
});

//get product by id
app.MapGet("/getproductbyid", async (int id, DbContextClass dbContext) =>
{
    var product = await dbContext.Product.FindAsync(id);
    if (product == null)
    {
        return Results.NotFound();
    }
    return Results.Ok(product);
});

//create a new product
app.MapPost("/createproduct", async (Product product, DbContextClass dbContext) =>
{
    var result = dbContext.Product.Add(product);
    await dbContext.SaveChangesAsync();
    return Results.Ok(result.Entity);
});

//update the product
app.MapPut("/updateproduct", async (Product product, DbContextClass dbContext) =>
{
    var productDetail = await dbContext.Product.FindAsync(product.ProductId);
    if (product == null)
    {
        return Results.NotFound();
    }
    productDetail.ProductName = product.ProductName;
    productDetail.ProductDescription = product.ProductDescription;
    productDetail.ProductPrice = product.ProductPrice;
    productDetail.ProductStock = product.ProductStock;

    await dbContext.SaveChangesAsync();
    return Results.Ok(productDetail);
});

//delete the product by id
app.MapDelete("/deleteproduct/{id}", async (int id, DbContextClass dbContext) =>
{
    var product = await dbContext.Product.FindAsync(id);
    if (product == null)
    {
        return Results.NoContent();
    }
    dbContext.Product.Remove(product);
    await dbContext.SaveChangesAsync();
    return Results.Ok();
});

app.Run();


Step 10
Run the following entity framework command to create migration and update the database
add-migration "initial"
update-database

Step 11
Finally, run your application

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



European ASP.NET Core Hosting - HostForLIFE :: ASP.NET Core 6.0 Blazor Server APP And Working With MySQL DB

clock October 17, 2022 09:38 by author Peter

In this article, we will see how to create a Stored Procedure in MySQL to search and bind the Customer details in our Blazor application using a Service with search parameter.

 

Blazor is a framework introduced by Microsoft. I love to work with Blazor as this makes our SPA full stack application development in simpler way and yes, now, we can use only one language, C#. Before Blazor, we were using ASP.NET Core with a combination of Angular or ReactJS. Now, with the help of Blazor support, we can create our own SPA application directly with C# Code.

We can develop two kinds of Blazor Applications which are Blazor Server App and another one is Blazor WebAssembly.

Blazor WebAssembly

WebAssembly or WASM runs on the client side. WebAssembly is the open web standard and works in browsers without support for any other plugins. WASAM uses JavaScript Interoperability to access the full functionality of browsers. Here we can see the structure of ASP.NET Core WASAM Application as the solution has only the client development as same structure of the ASP.NET Core Angular Stand-Alone Templates. For any server-side business logics or for using the Database we need to create an ASP.NET Core WEB API or other server-side project and bind the server-side data to the WASAM applications.

 

Blazor Server
Blazor Server which runs in the ASP.NET Server means its runs on Server side. Blazor Server App uses the SignalR to continuously push updates to the client side. All the JavaScript calls, UI updates and all the app event handling using the SignalR with WebSocket protocol connections. Blazor Server app is much faster than the WASAM as the download size is smaller than the WASAM applications. Here we can see the structure of ASP.NET Core Blazor Server Application as the solution has Data folder where we can write all server-side business logic and can use the service to perform the Database related connections.

Creating the Database and Table
Here using MySQL workbench we create database named as customer and created a table named as custmaster.

Create the Stored Procedure
Let’s create the stored procedure to perform and search and customer details with customer name and customer email.

CREATE DEFINER=`shanu`@`%` PROCEDURE `sp_custGet`(IN CustName varchar(50),
IN Email varchar(50)    )
BEGIN
Select  CustCd,
        CustName,
        Email,
        PhoneNo,
        Address
FROM customer.custmaster
WHERE
CustName LIKE CONCAT('%', CustName , '%')
AND
Email LIKE  CONCAT('%', Email , '%') ;
END

To test the Stored Procedure in MySQL we use the below code as a call with stored procedure name and now let's pass the empty parameter for both custname and email.


Blazor part
After installing all the prerequisites listed above and click Start >> Programs >> Visual Studio 2022 >> Visual Studio 2022 on your desktop. Click New >> Project.


Search for Blazor Server App project and click Next.


Enter your project name and click Next.

Select .NET 6.0 and click next to create your Blazor Application.

 

Step 2: Connection String
Open the appsettings.json file and add the MySQL connection string. Note add your MySQL server ID details.
"ConnectionStrings": {
    "DefaultConnection": "server=localhost;user id=-------;password=--------;port=3306;database=customer;"
},

Step 3: Install the Packages
In order to work with MySQL Database in our Blazor application here we use the install the below mentioned packages :

MySqlConnector
Microsoft.EntityFrameworkCore

Step 4: Create Model Class
Next, we need to create the Model class for using in our application for binding the Customer Details.
Let’s create a new folder named as Models from our solution and then Right click the created Models folder and create new class file as “CustMaster.cs”.
In the class, we add the property field name which is the same as the below code:
public class custmaster{
    public string CustCd { get; set; }
    public string CustName { get; set; }
    public string Email { get; set; }
    public string PhoneNo { get; set; }
    public string Address { get; set; }
}


Step 5: Create MySQL Connection Class
Now let’s create the MySQL connection class and for this let’s create a class file.
Right click the created Models folder and create new class file as mySQLSqlHelper.cs
using MySqlConnector;
namespace BlazorMysql.Models {
    public class mySQLSqlHelper {
        //this field gets initialized at Startup.cs
        public static string conStr;
        public static MySqlConnection GetConnection() {
            try {
                MySqlConnection connection = new MySqlConnection(conStr);
                return connection;
            } catch (Exception e) {
                Console.WriteLine(e);
                throw;
            }
        }
    }
}


Now open the Program.cs file and lets assign the connection string from our appsetting.json to the mysqlHelper constring variable for connecting to the MySQL.
using BlazorMysql.Data;
using BlazorMysql.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
var builder = WebApplication.CreateBuilder(args);

mySQLSqlHelper.conStr = builder.Configuration["ConnectionStrings:DefaultConnection"];


Step 6: Creating Customer MySql Connection class
Right Click the Data folder from the solution and add the new class named as custConnectoins .cs

In this class we create the GetCustDetails for connecting to Database and get the customer details by calling the Stored procedure with the required parameter passing and return to the list to our Service.
using BlazorMysql.Models;
using MySqlConnector;
using System.Data;
namespace BlazorMysql.Data {
    public class custConnectoins {
        public async Task < custmaster[] > GetCustDetails(string CustName, String Email) {
            List < custmaster > list = new List < custmaster > ();
            using(MySqlConnection conn = mySQLSqlHelper.GetConnection()) {
                conn.Open();
                using(MySqlCommand cmd = new MySqlCommand("sp_custGet", conn)) {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add(new MySqlParameter {
                        ParameterName = "@CustNames",
                            DbType = DbType.String,
                            Value = CustName,
                            Direction = ParameterDirection.Input,
                    });
                    cmd.Parameters.Add(new MySqlParameter {
                        ParameterName = "@Emails",
                            DbType = DbType.String,
                            Value = Email,
                            Direction = ParameterDirection.Input,
                    });
                    using(MySqlDataReader reader = cmd.ExecuteReader()) {
                        while (reader.Read()) {
                            list.Add(new custmaster() {
                                CustCd = reader.GetInt32("CustCd"),
                                    CustName = reader.GetString("CustName"),
                                    Email = reader.GetString("Email"),
                                    PhoneNo = reader.GetString("PhoneNo"),
                                    Address = reader.GetString("Address"),
                            });
                        }
                    }
                }
            }
            return list.ToArray();
        }
    }
}


Step 7: Working with Service Class
Next, we create the custMasterDetailSerivce.cs class and added the function named as GetCustDetails in order to bind the result to our Blazor apps.
using BlazorMysql.Models;
namespace BlazorMysql.Data {
    public class custMasterDetailSerivce {
        custConnectoins objUsers = new custConnectoins();
        public async Task < custmaster[] > GetCustDetails(string CustName, String Email) {
            custmaster[] custsObjs;
            custsObjs = objUsers.GetCustDetails(CustName, Email).Result.ToArray();
            return custsObjs;
        }
    }
}


Step 8: Add the Service
We need to add the services created by us to the Program.cs class.

builder.Services.AddSingleton<custMasterDetailSerivce>();

Step 9: Working with Client Project

First, we need to add the Razor Component page.

Add Razor Component
To add the Razor Component page, right click the Pages folder from the solution. Click on Add >> New Item >> Select Razor Component >> Enter your component name, here we have given the name as Customer.razor.

Note all the component files need to have the extension as .razor.

In Razor Component Page, we have three parts of code as first is the Import part where we import all the references and models for using in the component, HTML design and data bind part and finally we have the function part to Inject and call the service to bind in our HTML page and also to perform client-side business logic to be displayed in Component page.

Import Part
First, we import all the needed support files and references in our Razor View page. Here, we have first imported our Model and service class to be used in our view.
@page "/Customer"
@using BlazorMysql.Models
@using BlazorMysql.Data
@inject custMasterDetailSerivce CustomerService


HTML Design and Data Bind Part
In design part, we bind the result in table and also, we design a search part with button.
<h1>Customer Details</h1>
<table >
    <tr style="height: 30px; background-color:#336699 ; color:#FFFFFF ;border: solid 1px #659EC7;">
        <td colspan="5" align="left">
            Search Customer
        </td>
    </tr>
    <tr>
        <td>Cust Code:</td>
        <td>
            <input class="input-group-text" type="text" @bind-value="@CustName" />
        </td>
        <td>Cust Name:</td>
        <td>
            <input class="input-group-text" type="text" @bind-value="@Email" />
        </td>
        <td>
            <input type="button" class="btn btn-primary" value="Search" @onclick="@searchDetails" />
        </td>
    </tr>
</table>
<hr />
@if (custDetails == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Customer Code</th>
                <th>Customer Name</th>
                <th>Email</th>
                <th>Phone No</th>
                <th>Address</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var cuDetails in custDetails)
            {
                <tr>
                    <td>@cuDetails.CustCd</td>
                    <td>@cuDetails.CustName</td>
                    <td>@cuDetails.Email</td>
                    <td>@cuDetails.PhoneNo</td>
                    <td>@cuDetails.Address</td>
                </tr>
            }
        </tbody>
    </table>
}

Function Part
Function part to get the Service result and bind the result in array and we have created function to search and bind the result when button clicked. Here, first we declare the customer Array to get bind the result and declared variables for search.

In OnInitializedAsync, we get the CustomerService result and bind the result in the ItemsArrays.
@code {
    String CustName = "";
    String Email = "";
    private custmaster[] ? custDetails;
    protected override async Task OnInitializedAsync() {
        custDetails = await CustomerService.GetCustDetails(CustName, Email);
    }
    //SearchCustomer
    async Task searchDetails() {
        custDetails = await CustomerService.GetCustDetails(CustName, Email);
    }
}


Navigation Menu
Now, we need to add this newly added customer Razor page to our left Navigation. For adding this, open the Shared Folder and open the NavMenu.cshtml page and add the menu.
<div class="nav-item px-3">
    <NavLink class="nav-link" href="Customer">
         <span class="oi oi-list-rich" aria-hidden="true"></span> Customer
    </NavLink>
</div>


Build and Run the Application

Conclusion
Hope this article helps you to understand getting started with ASP.NET Core 6.0 and Blazor Application to work with MySQL Database with search functionality.

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core Hosting - HostForLIFE :: Hosting .NET Core Web API images With Docker Compose over HTTPS

clock October 10, 2022 08:17 by author Peter

We are going to discuss here SSL Certificate configuration for secure communication over the HTTPS using .NET Core Web API and Docker after running our application inside the docker container using docker-compose.

Introduction
    HTTPS is a standard internet protocol that makes the data to be encrypted and a more advanced and secure version of the HTTP protocol.
    SSL stands for Secure Sockets Layer and standard technology which keeps secure our application over the internet.
    SSL is the part of HTTPS protocol and it takes care of the encryption of data.
    It enables a secure connection and prevents hacker attacks because of its encryption algorithm and many security layers.

Implementation of .NET Core Web API Application

Step 1

Create a new .NET Core Web API application

Step 2
Configure your application

Step 3
Provide additional information

Step 4
Next, we create a certificate for the local machine using the following command
    dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\dockerdemo.pfx -p Pass@*****
    dotnet dev-certs https --trust


Here as you can see, we pass the certificate name and password in the above command and it will create the certificate at %USERPROFILE%\.aspnet\https this location

 

Step 5
Create a Docker file for our Weather Forecast application
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app

EXPOSE 443
EXPOSE 80

# copy project csproj file and restore it in docker directory
COPY ./*.csproj ./
RUN dotnet restore

# Copy everything into the docker directory and build
COPY . .
RUN dotnet publish -c Release -o out

# Build runtime final image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "HTTPSCertDemo.dll"]

Step 6
Here using this command, you can create a docker image inside the docker desktop (Note: Make sure docker desktop is working fine on your machine)
docker build . -t ssldemo:v1

Next, we run our application after setting port and certificate details using docker volume.

docker run -p 8081:80 -p 8082:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=7001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="Pass@*****" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/dockerdemo.pfx -v %USERPROFILE%\.aspnet\https:/https/ ssldemo:v1

Here you can see we provide two ports one is for HTTPS and another one is for HTTPS, also some environmental variables like port, certificate path, and credentials along with docker volume (Note: docker volume is basically the shared directory which persists the data with docker container which is created by the user like in this case we create a certificate and it located at our local system)

Step 7

Also, if we want to manage multiple docker images and their configuration efficiently, in that case, we can use the docker-compose file for managing all our application dynamic settings which we required when the application image is running inside the docker container for that we are going to create a docker-compose YAML file for the application
    version: '3.5'
    services:
      Weatherforecase.Service:
       image: ${DOCKER_REGISTRY-}ssldemo:v1
       build:
        context: ./HTTPSCertDemo
        dockerfile: Dockerfile
       environment:
        - ASPNETCORE_ENVIRONMENT=Development
        - ASPNETCORE_URLS=https://+:443;http://+:80
        - ASPNETCORE_Kestrel__Certificates__Default__Password=Pass@*****
        - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/dockerdemo.pfx
       ports:
        - "8081:80"
        - "8082:443"
       volumes:
        - ~/.aspnet/https:/https:ro


Here, you can see we provide different parameters with the help of environmental variables like docker image name, container name, certificate details, docker volume, and application port numbers

To run your application using the docker-compose YAML file for that use the following commands
docker-compose build
docker-compose up


Here one command is going to build and create a docker image inside the docker desktop and another one runs your application image inside the docker container and configure all dynamic settings which you passed inside the YAML file.

Step 8

Next, in the docker desktop, you can see the application is running inside the docker container


Also, inside the visual studio, we can see the details of containers as shown in the below images

 

Step 9
Finally, open both application URLs and use the application
http://localhost:8081/swagger/index.html


https://localhost:8082/swagger/index.html


 

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



European ASP.NET Core Hosting - HostForLIFE :: Options Pattern In .NET 6.0

clock October 6, 2022 08:09 by author Peter

In this tutorial, we are going to cover an approach through which we can read the configuration data in .NET Core - the options pattern.

Why the Options Pattern?

   Options pattern gives the below features
    It can be used to bind configuration data to strongly typed objects.
    It adheres to two important software engineering principles - Encapsulation and Separation of Concerns.
    It provides a mechanism to validate configuration data.

Please refer to the Microsoft documentation for more details.

Tools which I have used for this tutorial:
    Visual Studio 2022 Community Edition – Preview version 17.4 (Preview 2)
    .NET 6.0
    Web API
    Swagger

To begin with, let us create a sample project. The source code can be downloaded from GitHub.

Let us assume that we have the below configuration in appsettings.json
"OptionsTutorial": {
    "InterfaceName" : "IOptions"
}

Create the following class:
public class OptionsTutorial
{
    public const string Position = "OptionsTutorial";
    public string InterfaceName { get; set; }
}

Rules which need to be followed to create this class:
    Must be non-abstract with a public parameterless constructor.
    All public read-write properties of the type are bound.
    Fields are not bound. In the preceding code, “Position” is not bound.
    The “Position” field is used so the string " OptionsTutorial " doesn't need to be hard coded in the app when binding the class to a configuration provider.

Bind the configuration data to strongly typed objects.

In Program.cs class, we need to add the below line to bind the configuration data.
builder.Services
    .Configure< OptionsTutorial>(builder.Configuration.GetSection(OptionsTutorial.Position));

Use IOptions<T> Interface
This interface is registered as a Singleton and can be injected into any service lifetime.

This does not support:
    Read configuration data after the application has started.
    Named Options -  Refer to the Microsoft documentation for more details.

Let us make a few code changes in WeatherForecastController.cs

Add the below variable at the beginning of the class.
private OptionsTutorial _optionsTutorial;

make the below code changes in Constructor.
public WeatherForecastController(ILogger<WeatherForecastController> logger, IOptions<OptionsTutorial> options)
{
    _logger = logger;
    this._optionsTutorial = options.Value;
}


Introduce a new action method as below
[HttpGet]
[Route("optionspattern")]
public IActionResult OptionsPattern()
{
    var interfaceName = this._optionsTutorial.InterfaceName;
    var message = $"interface name from OptionsTutorial - {interfaceName}";
    return Ok(message);
}


Let us debug the action method and the result.

We can see that; the configuration data has been bound to the strongly typed object.

Use IOptionsSnapshot<T> Interface
    This interface is useful in scenarios where options need to be recomputed on every request. Please refer to the Microsoft documentation for more details on this.
    This interface has been registered as Scoped; hence it cannot be injected into Singleton Services.
    It supports Names Options.

Add the below settings in Appsettings.json
"SnapShot": {
    "InterfaceName": "IOptionsSnapshot"
}


Add the below interface and classes
public class SnapShot
{
    public const string Position = "Snapshot";
    public string InterfaceName { get; set; }
}

I have created two interfaces - ISnapShotCheckWithScope.cs and ISnapShotCheckWithSingleton.cs for validating the Singleton as well as Scoped service lifetime

Make the necessary changes in Program.cs
builder.Services.AddScoped<ISnapShotCheckWithScope, SnapShotCheckWithScope>();
/// UnComment this line and see whether the code executed or not.
/// you will get a runtime error
//builder.Services.AddSingleton<ISnapShotCheckWithSingleton, SnapShotCheckWithSingleton>();


As IOptionsSnapshot interface has been registered as Scoped, it cannot be injected into Singleton Services. Please look at the source code available in GitHub to understand more on this.

Let us go ahead and execute the Scoped controller.

Now change from Scoped to Singleton in Program.cs and see how this behaves.
//builder.Services.AddScoped<IOptionsMonitorCheck, OptionMonitorCheck>();
//Uncomment each of the below one at a time and see how this behaves
builder.Services.AddSingleton<IOptionsMonitorCheck, OptionMonitorCheck>();
//builder.Services.AddTransient<IOptionsMonitorCheck, OptionMonitorCheck>();

Successfully execute.

Now let us change to Transient in Program.cs and see.
//builder.Services.AddScoped<IOptionsMonitorCheck, OptionMonitorCheck>();
//Uncomment each of the below one at a time and see how this behaves
//builder.Services.AddSingleton<IOptionsMonitorCheck, OptionMonitorCheck>();
builder.Services.AddTransient<IOptionsMonitorCheck, OptionMonitorCheck>();

Execute successfully.

We have seen how to read configuration data using Options pattern in .NET 6.0. This approach will ensure two engineering principles – encapsulation and separation of concerns.  Hope this article helps you to understand the Options pattern at high level. Thank you for reading my article and please leave your comments in the comment box below.



European ASP.NET Core Hosting - HostForLIFE :: Sitecore Tokens For Standard Values

clock October 3, 2022 10:05 by author Peter

As Sitecore developers, when we're creating templates, a good practice is to add Standard Values so that fields can have default values or sample values.For this purpose, we can use Sitecore Tokens, this will allow us to dynamically add values to fields, according to the item that is being created by the Content Author.

Tokens

These are the tokens that we can use:

Token Utility
$name The name of the item.
$id The ID of the item.
$parentid The ID of the parent of the item.
$parentname The name of the parent of the item.
$date The system date (yyyyMMdd).
$time The system time (HHmmss).
$now The system date and time (yyyyMMddTHHmmss).

Example

Below we can see an example with the $name token. In this example, we have a field with the name Heading, and at the time of creating a new item, this field will take the name of the item.

Thanks for reading!
Now you know how to add automatic generation of field values and the different tokens you can use in a general way.
If you have any questions or ideas in mind, it will be a pleasure to be able to be in communication with you, and together exchange knowledge with each other.

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET SignalR Hosting - HostForLIFE :: Using ASP.NET SignalR for Chat Application

clock September 27, 2022 10:42 by author Peter

Nowadays, chat applications have become pretty common. But still, the idea of how a client gets the message from the server without asking for it or in other words, without any event being fired, is remarkable. Such applications are known as real-time applications because they are responsible for live data exchange as used in multiplayer games, social media, or news forecasts. In real-time applications, the server pushes the message to connected clients instantly it becomes available to all connected clients. So, in this article, we will build a real-time chatting/twaddling application using SignalR. SignalR uses simple Web APIs to connect a server Hub to all of its clients basically, by creating server-to-client RPC (Remote Procedure Calls) that calls JavaScript methods in client browsers from the server and vice-versa.
 
Let's start building a twaddling application which would allow the user to share messages to all users as well as to individual users privately. Firstly, we start by creating a new web application project with MVC template in your visual studio. Then, you need to add the Microsoft.AspNet.SignalR NuGet package reference to the newly created project. After adding the reference, we have to register the SignalR Hub APIs by just calling the predefined method MapHubs() of RouteTableCollection at global.asax. But what does registering of hubs mean? It implies creating a route of the hub URLs and maps each to all the hubs in our project. Here is a demo of how API URLs are registered in the global.asax file,
    public class MvcApplication : System.Web.HttpApplication  
    {  
        protected void Application_Start()  
        {  
            BundleConfig.RegisterBundles(BundleTable.Bundles);  
            AreaRegistration.RegisterAllAreas();  
            RouteTable.Routes.MapHubs();  
            RouteConfig.RegisterRoutes(RouteTable.Routes);  
        }  
    }  


Now, we will create our own hub which will communicate with our client-side's javascript by just inheriting Microsoft.AspNet.SignalR.Hub class. This base class provides us with three properties and three virtuals methods, which would help us build our hub, namely,
    Clients: A collection of all the clients connected to the hub.
    Groups: A collection of groups of clients, mainly used for managing groups of clients.
    Context: Stores the details of that client which has called the server method.
    connected(): Triggered when a client joins the hub for the first time.
    OnDisconnected() : Triggered when a client leaves a hub.
    OnReconnected(): Triggered when a client joins the hub for the next time.

By using this properties and method, we create a hub named MasterHub where we will mainly have our broadcasting logics. So, now its time to define the client methods used in MasterHub but before that, we need to create a hub proxy by adding a script reference of ~/signalr/hubs and start that proxy by calling the predefined method $.connection.hub.start(). Here is an example how to create a hub proxy and declare all the client methods,
    <script src="~/signalr/hubs"></script>  
    <script type="text/javascript">  
    $(window).load(function () {  
        let hub = $.connection.masterHub;  
        //define all your client-side methods  
        hub.client.LogIn = function (parameters) {  
        //define the client side logics  
        }  
        //finally start the hub proxy  
        $.connection.hub.start().done(function () {  
            $.fn.TwaddlerLogIn(hub);  
        });  
    });  
    </script>  


Your application is ready for a run. The first step for the client is to get connected to the hub by entering his name.

    public class MasterHub : Hub  
    {  
        private static List<Twaddler> Twaddlers = new List<Twaddler>();  
      
        private static List<TwaddleDetails> Twaddles = new List<TwaddleDetails>();  
      
        public void OnConnected(string TwaddlerName)  
        {  
            if (!Twaddlers.Any(x => Equals(x.ConnectionId, Context.ConnectionId)))  
            {  
                var twaddler = new Twaddler()  
                {  
                    Name = TwaddlerName,  
                    ConnectionId = Context.ConnectionId  
                };  
      
                Twaddlers.Add(twaddler);  
                Clients.Caller.LogIn(twaddler, Twaddlers, Twaddles);  
      
                //broadcast the new twaddler to all twaddlers  
                Clients.AllExcept(Context.ConnectionId).TwaddlerLogIn(twaddler);  
            }  
        }  


Then, the client could send a message to all the clients in the hub, globally.
 

    public void BroadcastTwaddle(TwaddleDetails twaddle)  
    {  
        Twaddles.Add(twaddle);  
        //broadcast the new twaddle to all twaddlers  
        Clients.All.BroadcastTwaddle(twaddle);  
    }  

The client could also send a private message to any specific hub, privately.

    public void PrivateTwaddle(string reciverId, string message)  
    {  
        var reciver = Twaddlers.Find(x => Equals(x.ConnectionId, reciverId));  
        if (reciver == null)  
            return;  
      
        var sender = Twaddlers.Find(x => Equals(x.ConnectionId, Context.ConnectionId));  
        if (sender == null)  
            return;  
      
        var privateTwaddle = new TwaddleDetails()  
        {  
            Twaddler = sender.Name,  
            TwaddleContent = message  
        };  
      
        Clients.Client(reciverId).PrivateTwaddle(sender.ConnectionId, privateTwaddle);  
        Clients.Caller.PrivateTwaddle(reciver.ConnectionId, privateTwaddle);  
    }  


And lastly, inform other clients when this client gets disconnected.



    public override Task OnDisconnected()  
    {  
        var twaddler = Twaddlers.Find(x => Equals(x.ConnectionId, Context.ConnectionId));  
        if (twaddler != null)  
        {  
            Twaddlers.Remove(twaddler);  
      
            //broadcast the twaddler has loggedout to all twaddlers  
            Clients.All.BoradcastTwaddlerLogOut(twaddler);  
        }  
        return base.OnDisconnected();  
    }  


Finally, you have successfully used SignalR to build your own real-time application which allows users to create private as well as global chat rooms by just writing a few server and client methods. Click here to get to the Twaddler project repository.

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core Hosting - HostForLIFE :: gRPC Introduction And Implementation Using .NET Core 6

clock September 26, 2022 09:24 by author Peter

We are going to discuss the gRPC and its implementation using .NET Core 6

Agenda
    Introduction of gRPC
    Different scenarios in which we use gRPC
    Pros and Cons of gRPC
    Implementation of gRPC

Prerequisites

    Visual Studio 2022
    Basic Knowledge of C#

Introduction

    gRPC stands for Google Remote Procedure Calls
    gRPC is a modern open-source high-performance Remote Procedure Call (RPC) framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking, and authentication. It is also applicable in the last mile of distributed computing to connect devices, mobile applications, and browsers to backend services. – gRPC Page

 

    gRPC is the framework that is used to implement APIs using HTTP/2
    Basically, gRPC uses the protobuf for serialization and HTTP2 protocol which provides lots more advantages than HTTP
    gRPC clients and servers intercommunicate using a variety of environments and machines, It Also supports many languages like Java, C#, Go, Ruby and Python.
    The Binary layer of gRPC will do all data operations like encoding and it also uses protobuf as an intermediator between client and server, improving performance.
    It is also used for communication between multiple microservices efficiently

Different scenarios in which we use gRPC

    When we use microservice architecture and we use that for internal communication from one or more servers
    It is also useful when performance is on high priority and low latency
    When we require duplex communication between services with different types of data

Pros and Cons of gRPC
Pros
    High Performance - faster than REST and SOAP
    Lightweight Message - gRPC Message is more lightweight than other types like JSON
    High Efficiency than other type
    Duplex data streaming

Cons
    Limited Browser Support
    It uses Binary Data due that it’s not easily readable like JSON and XML

Implementation of gRPC

Step 1
Create a new gRPC project

Step 2
Configure the project


Step 3
Provide additional information

Step 4
Project Structure

Here you will see the default project structure with greet proto and Greeter Service

syntax = "proto3";

option csharp_namespace = "GrpcService";

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings.
message HelloReply {
  string message = 1;
}

    Protobuf is Interface Definition Language (IDL) for gRPC and uses to store data and contracts between clients and servers
    Line No 1 to 5 as you see there we declare types of protobuf syntax, namespace, and package
    Line No 7 to 11 there is a Unary Service Definition which takes a single request and the server sends back the response and it works as a function
    There are also many service definitions like Server Streaming, Client Streaming, and Bidirectional streaming RPCs. If you want to learn more about then read the grpc.io document
    Later on, there is a request and response function in order

using Grpc.Core;
namespace GrpcService.Services
{
    public class GreeterService : Greeter.GreeterBase
    {
        private readonly ILogger<GreeterService> _logger;
        public GreeterService(ILogger<GreeterService> logger)
        {
            _logger = logger;
        }

        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }
}


This is the Greeter Service which inherits from Greeter.GreeterBase and inside that we inject ILogger and there is one method which takes the message to send by the client and send back as a response

(Note: Build Application whenever you add a new proto and Service)

Also, make sure the proto property is configured properly as shown below

Here we can see Build Action Protobuf compiler and gRPC Stub Classes are Server only

Let’s create a Client Console Application

Step 1
Create a new console application


Step 2
configure your project

Step 3
provide additional information

Step 4

Copy greet proto file from the server and change the gRPC Stub Classes to Client only and build it

Step 5
Add client code inside the Program file

using Grpc.Net.Client;
using GrpcService;
using GrpcService.Protos;
var message = new HelloRequest {
    Name = "Jaydeep"
};
var channel = GrpcChannel.ForAddress("http://localhost:5045");
var client = new Greeter.GreeterClient(channel);
var srerveReply = await client.SayHelloAsync(message);
Console.WriteLine(srerveReply.Message);
Console.ReadLine();

    Here we create a channel after configuring the server’s URL and create a channel
    Later on, call the method after passing a parameter to the server and print the response message inside the console

Step 6
Finally, run your code after configuring your both project as startup projects in proper order

This is the final output
Now we are going to add our new proto and service related to the product application in that we pass the product id from the client and the server will send the particular product details back to the client

Step 1
Create a new product proto file and change properties to Protobuf compiler and Servers only after that build the project
syntax = "proto3";

option csharp_namespace = "GrpcService.Protos";

package product;

service Product {
    rpc GetProductsInformation (GetProductDetail) returns (ProductModel);
}

message GetProductDetail{
    int32 productId = 1;
}

message ProductModel{
    string productName = 1;
    string productDescription = 2;
    int32 productPrice = 3;
    int32 productStock = 4;
}

Here you can see, that we define service which takes product id as a parameter and send product details to the client

Step 2
Next, create a Product Service
using Grpc.Core;
using GrpcService.Protos;

namespace GrpcService.Services
{
    public class ProductService : Product.ProductBase
    {
        private readonly ILogger<ProductService> _logger;
        public ProductService(ILogger<ProductService> logger)
        {
            _logger = logger;
        }

        public override Task<ProductModel> GetProductsInformation(GetProductDetail request, ServerCallContext context)
        {
            ProductModel productDetail = new ProductModel();
            if (request.ProductId == 1)
            {
                productDetail.ProductName = "Samsung TV";
                productDetail.ProductDescription = "Smart TV";
                productDetail.ProductPrice = 35000;
                productDetail.ProductStock = 10;
            }
            else if (request.ProductId == 2)
            {
                productDetail.ProductName = "HP Laptop";
                productDetail.ProductDescription = "HP Pavilion";
                productDetail.ProductPrice = 55000;
                productDetail.ProductStock = 20;
            }
            else if (request.ProductId == 3)
            {
                productDetail.ProductName = "IPhone";
                productDetail.ProductDescription = "IPhone 12";
                productDetail.ProductPrice = 65000;
                productDetail.ProductStock = 30;
            }

            return Task.FromResult(productDetail);
        }
    }
}


Here you can see we create Product Service which inherits from Product.ProductBase and after that, we inject ILogger of type Product Service and create one method and inside that whatever product details client wants that we check and return as a response corresponding to the particular product which is sent by the client

Step 3
Map the Product Service inside the Program class
using GrpcService.Services;
var builder = WebApplication.CreateBuilder(args);
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
// Add services to the container.
builder.Services.AddGrpc();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService < GreeterService > ();
app.MapGrpcService < ProductService > ();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();


Step 4
Build Server Project

Step 5
Copy the Product protobuf file inside the client and change the properties to the client only
syntax = "proto3";
option csharp_namespace = "GrpcService.Protos";
package product;
service Product {
    rpc GetProductsInformation(GetProductDetail) returns(ProductModel);
}
message GetProductDetail {
    int32 productId = 1;
}
message ProductModel {
    string productName = 1;
    string productDescription = 2;
    int32 productPrice = 3;
    int32 productStock = 4;
}

Step 6
Next, add client functionality inside the Program class
using Grpc.Net.Client;
using GrpcService;
using GrpcService.Protos;
//var message = new HelloRequest { Name = "Jaydeep" };
//var channel = GrpcChannel.ForAddress("http://localhost:5045");
//var client = new Greeter.GreeterClient(channel);
//var srerveReply = await client.SayHelloAsync(message);
//Console.WriteLine(srerveReply.Message);
//Console.ReadLine();
var channel = GrpcChannel.ForAddress("http://localhost:5045");
var client = new Product.ProductClient(channel);
var product = new GetProductDetail {
    ProductId = 3
};
var serverReply = await client.GetProductsInformationAsync(product);
Console.WriteLine($ "{serverReply.ProductName} | {serverReply.ProductDescription} | {serverReply.ProductPrice} | {serverReply.ProductStock}");
Console.ReadLine();


Here we create a channel after configuring the server’s URL and after that create a model object with a user id and pass it to the method which gets the product details as a response. Finally, we just print the product details in the console

Step 7

Build and run your both projects after setting up as a startup project

So, this is the output of our service.

In this section, we just understand the basic working of gRPC with Product Application. But, in real-time scenarios, there are many ways to implement that like using Background service and some different gRPC streaming techniques that we discussed in upcoming articles

Conclusion
In this article, we discussed gRPC, Pros, and Cons of gRPC. Also, the scenarios in which gRPC plays an important role and step-by-step implementation using .NET Core 6

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.



European ASP.NET Core Hosting - HostForLIFE :: Feature Flag In .NET 6.0

clock September 21, 2022 09:22 by author Peter

Feature flags also referred to as Feature Toggles are a powerful way to modify applications behavior without making any changes in the code. It allows features to be turned on and off dynamically.

In this tutorial, we are going to look at the below,

    Feature Management Library in .NET
    How can we use Feature Management Library in ASP.NET Core applications
    How to add a simple Boolean feature flag.
    Advanced Feature Flag filters.
    Custom Feature Flag Filter.

Feature Management Library

The .NET Core Feature Management Library extends the framework with comprehensive feature flag support. These libraries are built on top of the .NET Core Configuration system. Any .NET Core configuration provider can act as a backbone for feature flags.

The definition which I copied from GitHub.

“The Microsoft.FeatureManagement library enables developers to use feature flags and dynamic features inside of their applications. Feature flags can be used to turn features on or off dynamically. Developers can use feature flags in simple use cases like conditional statements to more advanced scenarios like conditionally adding routes or MVC filters. Dynamic features can be used to select different variants of a feature's configuration. This enables the possibility of using one version of a feature for one set of users, and another version of the feature for the remaining users”
Use Feature Management Library in ASP.NET Core

The tools which I have used for this tutorial are below

    VS 2022 Community Edition Preview Version 17.4 - Preview 2.0
    .NET 6.0
    Web API
    Swagger

Without any further delay, let us create an ASP.NET Core API project. Then add the below package from the NuGet.

Microsoft.FeatureManagement.AspNetCore
Add a simple Boolean Feature Flag

As we have successfully installed the NuGet package, let us go ahead and Feature flag into the Controller “WeatherForecastController”
To add the Feature flag, we need to inject an interface called “IFeatureManager”. This interface belongs to the NuGet package “Microsoft.FeatureManagement.AspNetCore”

The WeatherForecastController constructor would be looks like below
private readonly IFeatureManager _featureManager;
public WeatherForecastController(ILogger < WeatherForecastController > logger, IFeatureManager featureManager) {
    _logger = logger;
    this._featureManager = featureManager;
}


Now, we are going to add the Feature flag in the endpoint method –“GetWeatherForecast”
By default, this method returns list of WeatherForecast with properties Date, TemperatureC, and Summary. The GetWeatherForecast method given below
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable < WeatherForecast > Get() {
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast {
        Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    }).ToArray();
}

Let us go ahead and add a new feature called “TemperatureF” into the Model – “WeatherForecast”
public class WeatherForecast {
    public DateTime Date {
        get;
        set;
    }
    public int TemperatureC {
        get;
        set;
    }
    public string ? Summary {
        get;
        set;
    }
    //New Feature
    public int TemperatureF {
        get;
        set;
    }
}


While building this feature, we need to feature flag this new property as we are not sure when this is going to be deployed into production. So, we need to provide an ability to on and off this feature as we develop it. Let us start using the Feature Manager to determine this.

The updated GetWeatherForecast endpoint method is given below
[HttpGet(Name = "GetWeatherForecast")]
public async Task < IEnumerable < WeatherForecast >> Get() {
    //Feature Flag - this needs to be configure in AppSettings.json
    var isTemperatureFEnabled = await _featureManager.IsEnabledAsync("TemperatureF");
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast {
        Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            //check whether the Feature Flag is enabled
            TemperatureF = isTemperatureFEnabled ? (int)(Random.Shared.Next(-20, 55) * 1.8) + 32 : null,
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    }).ToArray();
}

Now we need to configure this Feature flag in any of the configuration source. In this tutorial, we are going to configure in AppSettings.json
"FeatureManagement": {
    "TemperatureF": true
}


The next step – we need to register the IFeatureManagement interface into dependency container. Now let us go to Program.cs and add the below line of code
builder.Services.AddFeatureManagement();

We have completed the configuration. Let us go ahead and execute the Endpoint GetWeatherForecast, we will get the below response
[{
        "date": "2022-09-17T23:08:43.4688307-04:00",
        "temperatureC": 25,
        "summary": "Balmy",
        "temperatureF": 37
    }, {
        "date": "2022-09-18T23:08:43.4693542-04:00",
        "temperatureC": 44,
        "summary": "Warm",
        "temperatureF": 44
    }, {
        "date": "2022-09-19T23:08:43.4693578-04:00",
        "temperatureC": -14,
        "summary": "Mild",
        "temperatureF": 91
    }

We can see that the new Feature “TemparatureF” has been returned.

Now let us go to disable this feature in AppSettings.json and execute the endpoint
"FeatureManagement": {
    "TemperatureF": false
}


Now execute the endpoint and look at the response.
[{
        "date": "2022-09-17T23:11:51.823846-04:00",
        "temperatureC": -17,
        "summary": "Hot",
        "temperatureF": null
    }, {
        "date": "2022-09-18T23:11:51.8238573-04:00",
        "temperatureC": 28,
        "summary": "Chilly",
        "temperatureF": null
    }, {
        "date": "2022-09-19T23:11:51.8238577-04:00",
        "temperatureC": 29,
        "summary": "Freezing",
        "temperatureF": null
    }


The TemperatureF has been displayed with “null” value. This property can be turned off altogether when it is null. To do that, go to Startup.cs and add the below lines of code.
//Ignore Null Values
builder.Services.AddControllers().AddJsonOptions(option => {
    option.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
});


Now, let us go ahead and execute the code and see what the response would be.
[{
        "date": "2022-09-17T23:21:36.5978036-04:00",
        "temperatureC": 20,
        "summary": "Chilly"
    }, {
        "date": "2022-09-18T23:21:36.5981674-04:00",
        "temperatureC": 19,
        "summary": "Freezing"
    }, {
        "date": "2022-09-19T23:21:36.5981699-04:00",
        "temperatureC": -19,
        "summary": "Bracing"
    }


TemperatureF property is not visible

Feature Flag Filters
Let us go ahead and add a new endpoint as below
[HttpGet("newfeature")]
public async Task < IEnumerable < WeatherForecast >> GetNewEndPoint() {
    //Feature Flag - this needs to be configure in AppSettings.json
    var isTemperatureFEnabled = await _featureManager.IsEnabledAsync("TemperatureF");
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast {
        Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            //check whether the Feature Flag is enabled
            TemperatureF = isTemperatureFEnabled ? (int)(Random.Shared.Next(-20, 55) * 1.8) + 32 : null,
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    }).ToArray();
}

We are going to add feature flag to this method. Let us see how this can be achieved. Rather than we do an event check insider the method, we can simply add the below attribute at the method level to flag this method as a feature.
[FeatureGate("NewFeature")] – here “NewFeature” is the value of the feature flag

This attribute belongs to the namespace – “Microsoft.FeatureManagement.Mvc”

The updated method looks like below,
[HttpGet("newfeature")]
[FeatureGate("NewFeature")]
public async Task < IEnumerable < WeatherForecast >> GetNewFeature() {
    //Feature Flag - this needs to be configure in AppSettings.json
    var isTemperatureFEnabled = await _featureManager.IsEnabledAsync("TemperatureF");
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast {
        Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            //check whether the Feature Flag is enabled
            TemperatureF = isTemperatureFEnabled ? (int)(Random.Shared.Next(-20, 55) * 1.8) + 32 : null,
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    }).ToArray();
}

Now, let us go ahead and add this feature flag in AppSettings.json
"FeatureManagement": {
    "TemperatureF": false,
    "NewFeature": true
}


Let us go ahead and execute the endpoint
WeatherForecast/newfeature
[{
        "date": "2022-09-19T00:19:43.2623594-04:00",
        "temperatureC": 1,
        "summary": "Freezing"
    }, {
        "date": "2022-09-20T00:19:43.2651919-04:00",
        "temperatureC": 7,
        "summary": "Cool"
    }, {
        "date": "2022-09-21T00:19:43.2652001-04:00",
        "temperatureC": 26,
        "summary": "Scorching"
    }

Now update the “NewFeature” flag in AppSettings.json as below,
"FeatureManagement": {
    "TemperatureF": false,
    "NewFeature": false
} {
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
    "title": "Not Found",
    "status": 404,
    "traceId": "00-4a24d9885877e1d886949c330cd2dd16-35b5ed50d738cba3-00"
}


We got the 404 error.

In the upcoming tutorial, I will be explaining Advanced Feature Flag and Custom Feature flag.

Thank you for reading my article.

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



European ASP.NET Core Hosting :: Create Window Service In .NET Core

clock September 12, 2022 10:40 by author Peter

In this article, we will learn how to create a window service with .NET Core using Quartz Cron expression. And host an application as a windows service on the server machine.

Step 1
To begin, make a project with the.NET core console application template.

Step 2
Install Required packages for Host Builder using Nuget Package Manager.

Host Builder Introduction
Host Builder is the new “generic” Host which enables developers to easily set up cross-cutting concerns such as logging, configuration, and dependency injection for non-web-focused applications. The team realized that having the host tied to the concern of HTTP was perhaps not an ideal solution since many of these are common requirements in other application types.

An example of where this could be used is in a console application that needs to run background processing tasks, perhaps handling messages on a queue for example. These types of services are now pretty common in a cloud-native, container-based architecture.

Step 3
Install the required package for Quartz using Nuget Package Manager.

Also, install Quartz using the Package Manager Console as below:
NuGet\Install-Package Quartz -Version 3.4.0

Step 4
Once package install is completed we can write code for the scheduler which will run after a specific amount of time. Please find below sample code to write in program.cs file to write log at specific amount of time.
class Program {
    static async Task Main(string[] args) {
        IHost Host = CreateHostBuilder(args).Build();
        await Host.RunAsync();
    }
    public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureServices(services => {
        ConfigureQuartzService(services);
        services.AddScoped < ITaskLogTime, TaskLogTime > ();
    });
    private static void ConfigureQuartzService(IServiceCollection services) {
        // Add the required Quartz.NET services
        services.AddQuartz(q => {
            // Use a Scoped container to create jobs.
            q.UseMicrosoftDependencyInjectionJobFactory();
            // Create a "key" for the job
            var jobKey = new JobKey("Task1");
            // Register the job with the DI container
            q.AddJob < Task1 > (opts => opts.WithIdentity(jobKey));
            // Create a trigger for the job
            q.AddTrigger(opts => opts.ForJob(jobKey) // link to the Task1
                .WithIdentity("Task1-trigger") // give the trigger a unique name
                .WithCronSchedule("0/5 * * * * ?")); // run every 5 seconds
        });
        // Add the Quartz.NET hosted service
        services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
    }
}


Cron Trigger Introduction
As we utilize quartz we can use a cron trigger. Cron is nothing but it is a UNIX tool that has been around for a long time, so its scheduling capabilities are powerful and proven. The CronTrigger class is based on the scheduling capabilities of cron.

As for POC added cron trigger for 5 seconds with the below expression

"0/5 * * * * ?"

Create a trigger and added to quartz like the below code,
private static void ConfigureQuartzService(IServiceCollection services) {
    // Add the required Quartz.NET services
    services.AddQuartz(q => {
        // Use a Scoped container to create jobs.
        q.UseMicrosoftDependencyInjectionJobFactory();
        // Create a "key" for the job
        var jobKey = new JobKey("Task1");
        // Register the job with the DI container
        q.AddJob < Task1 > (opts => opts.WithIdentity(jobKey));
        // Create a trigger for the job
        q.AddTrigger(opts => opts.ForJob(jobKey) // link to the Task1
            .WithIdentity("Task1-trigger") // give the trigger a unique name
            .WithCronSchedule("0/5 * * * * ?")); // run every 5 seconds
    });
    // Add the Quartz.NET hosted service
    services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
}


Step 5
Build and Run the application using exe file. Please find attached the full source code which will write the log to log.txt file for a current time after every 5 sec as per our cron expression.

Start exe


Check Log folder for the result

Step 6
As we run our application manually using exe file. Now sit back and think on server do we run our application like this is a good practice. Not a good idea. So below is the solution.

Host dotnet core console application as a window service

Please follow the below steps to host a console application as a window service.

Required Code changes
To support the window service console application, need to allow UseWindowsService in

CreateHostBuilder met method.

To use window service need to install the NuGet package
‘Microsoft.AspNetCore.Hosting.WindowsServices’

To install it by command use “Install-Package Microsoft.AspNetCore.Hosting.WindowsServices - Version”

Note
Need to install the package as per your .NET core version compatibility.

Change in Program.cs file.
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).UseWindowsService().ConfigureServices(services => {
    ConfigureQuartzService(services);
    services.AddScoped < ITaskLogTime, TaskLogTime > ();
});


Once code changes are done Publish the application in Release mode.

After publishing the application, open Command Prompt in administrator mode.

Command To Create Service > SC CREATE "ServiceName" binpath="D:\Published \application\path\application.exe"

Command To Remove Service > SC DELETE ServiceName

Once the service is created. Open press win + R > Type services.msc > Enter.

Service should be visible here by the name you have entered during creation.

Start and stop service from here and change the configuration as per requirement. (I.e. login by another user, automatic or manual)

Advantage
    The server admin is not required to run an exe file on the server manually.
    Server admin can set different credentials as per requirement.
    It can be set as an automatic or manual start. so whenever the server is down and restarted no need to check it will automatically start service as per configuration.

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



European ASP.NET Core Hosting :: JWT Token Creation, Authentication And Authorization In ASP.NET Core 6.0 With Postman

clock September 6, 2022 07:38 by author Peter

In this article, I will explain how to create the JWT token and how to Authenticate and Authorize it in very simple steps. We will follow the below steps to JWT token creation, authentication and authorization.

  • ASP.Net Core API Application
  • Add required packages.
  • Add Key, Issuer and Audience in appsettings.cs
  • Register JWT Token for Authentication in Startup.cs file.
  • Create Models (UserLogin, UserModel and UserConstant)
  • Create Login API Controller (Authenticate user and generate token)
  • Create User API Controller to authorize user role.
  • Test the API endpoint in Postman with Token.

1. Add ASP.Net Core API Application
Open visual studio 2022 click on create new project --> Select ASP.Net Core Web API --> Next

Give desired project and solution name --> Next --> select framework .Net 6.0 --> Create

2. Add Nuget Packages
Add the following packages from nuget package manager.
    Microsoft.AspNetCore.Authentication.JwtBearer
    Microsoft.IdentityModel.Tokens
    System.IdentityModel.Tokens.Jwt

 


3. Add setting in appsetting.json
Open appsetting.json and add following Key, Issuer and Audience

* To generate the random key use
https://www.random.org/strings

* For issuer and audience local URL follow the below steps
Project properties --> Debug --> General --> Open Debug Launch Profile UI


Select IIS Express and pick the App URL

"Jwt": {
    "Key": "ACDt1vR3lXToPQ1g3MyN", //Generate random String from https://www.random.org/strings
    "Issuer": "http://localhost:28747/", //Project Property-> Debug-> IIS-->App URL (you can local host url as well)
    "Audience": "http://localhost:28747/"
  },

4. Register JWT token for Authentication in Program.cs file

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//JWT Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
    options.TokenValidationParameters = new TokenValidationParameters {
        ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

5. Create Models (UserLogin, UserModel and UserConstant)
Add a new folder with Models name and create UserLogin, UserModel and UserConstant classes.

namespace JWTLoginAuthenticationAuthorization.Models
{
    public class UserModel
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string Role { get; set; }
    }
}

namespace JWTLoginAuthenticationAuthorization.Models
{
    public class UserLogin
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

namespace JWTLoginAuthenticationAuthorization.Models
{
    // We are not taking data from data base so we get data from constant
    public class UserConstants
    {
        public static List<UserModel> Users = new()
            {
                    new UserModel(){ Username="naeem",Password="naeem_admin",Role="Admin"}
            };
    }
}

6. Create LoginAPI Controller (Authenticate user and generate token)
Add a new Empty API controller name “LoginController” in controller folder.

 

Here creates one Post Action method for Login and two methods for Authenticating the user credentials and Generate the token (if user is authenticated).

using JWTLoginAuthenticationAuthorization.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace JWTLoginAuthenticationAuthorization.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class LoginController : ControllerBase
    {
        private readonly IConfiguration _config;
        public LoginController(IConfiguration config)
        {
            _config = config;
        }

        [AllowAnonymous]
        [HttpPost]
        public ActionResult Login([FromBody] UserLogin userLogin)
        {
            var user = Authenticate(userLogin);
            if (user != null)
            {
                var token = GenerateToken(user);
                return Ok(token);
            }

            return NotFound("user not found");
        }

        // To generate token
        private string GenerateToken(UserModel user)
        {
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier,user.Username),
                new Claim(ClaimTypes.Role,user.Role)
            };
            var token = new JwtSecurityToken(_config["Jwt:Issuer"],
                _config["Jwt:Audience"],
                claims,
                expires: DateTime.Now.AddMinutes(15),
                signingCredentials: credentials);


            return new JwtSecurityTokenHandler().WriteToken(token);

        }

        //To authenticate user
        private UserModel Authenticate(UserLogin userLogin)
        {
            var currentUser = UserConstants.Users.FirstOrDefault(x => x.Username.ToLower() ==
                userLogin.Username.ToLower() && x.Password == userLogin.Password);
            if (currentUser != null)
            {
                return currentUser;
            }
            return null;
        }
    }
}

7. Create User API Controller to authorize user role
Add new empty API controller named “UserController.cs” in controller folder.
Here we will authorize the endpoint on the behalf of role.

namespace JWTLoginAuthenticationAuthorization.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        //For admin Only
        [HttpGet]
        [Route("Admins")]
        [Authorize(Roles = "Admin")]
        public IActionResult AdminEndPoint()
        {
            var currentUser = GetCurrentUser();
            return Ok($"Hi you are an {currentUser.Role}");
        }
        private UserModel GetCurrentUser()
        {
            var identity = HttpContext.User.Identity as ClaimsIdentity;
            if (identity != null)
            {
                var userClaims = identity.Claims;
                return new UserModel
                {
                    Username = userClaims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier)?.Value,
                    Role = userClaims.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value
                };
            }
            return null;
        }
    }
}

8. Test the API endpoint in Postman with Token
Run the application and copy the URL domain from the browser.
Now open the Postman, give the URL with correct API route and select post request --> Body --> Json --> give the value of Username and Password
.

After clicking on send button we will get the JWT token in response.

Now copy this token and add a new Get request in postman and add the JWT token Authorization Tab --> Select Bearer --> Insert token and click on send button to test the authorization with given token. If the token is not valid token then we will get 401 Error otherwise will get the bolow result.

So we created the token and did the authentication on the behalf of username and password then check the user authorization.

HostForLIFE.eu ASP.NET Core Hosting

European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.




About HostForLIFE

HostForLIFE 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 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in