Sunday, 29 January 2023

Angular authentication

Here I am providing only code snippet, required for angular authentication. If you are angular guy then you will understand the code easily and use in your application.

I have a User Model. Below is the code.

1- Creating user model

export class User {
    isAuth = false;
    userId: string;
    email: string;
    password: string;
    name: string;
    address: string;
    role: string;
    roles = [];
    token: string;
    contact: string;
    createdDate: any;
    updatedDate: any;
    costructor() { }
}


Environment.ts file code snippet.

export const environment = {
  production: false,
  apiAddress: 'http://localhost:1300/api',
}



2- Creating AuthService

First we will create a Auth service in Angular. Below is the code for AuthService.

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { UserLogin } from '../public/models/userLogin';
import { Observable } from 'rxjs/Rx';

import { User } from '../models/user';
import { environment as env } from '../../environments/environment';

declare const localStorage: any;

@Injectable()
export class AuthService {
    headers: Headers;
    user: User;
    constructor(private http: Http) {
        this.headers = new Headers({ 'content-type': 'application/json' });
        this.loadAuthUser();
    }
    loadAuthUser() {
      if (localStorage['authInfo'] !== undefined && localStorage['authInfo'] !== null) {
            this.user = JSON.parse(localStorage['authInfo']);
      }
    }
    SignOut() {
        localStorage.removeItem('authInfo');
        this.user = undefined;
    }
    setAuthUser(user: User) {
        localStorage['authInfo'] = JSON.stringify(user);
        this.user = user;
    }
    ValidateUser(user: UserLogin): Observable<User> {
        return this.http.post(env.apiAddress + '/auth', JSON.stringify(user),
            { headers: this.headers }).map((res) => {
                return res.json();
            }).catch((err) => Observable.throw(err));
    }
}


3- Creating LoginComponent code

Then We will call Login function for user authentication and token storage. Below is the code for Login Component.

import { Component, OnInit } from '@angular/core';
import { UserLogin } from '../models/userLogin';
import { AuthService } from '../../services/auth.service';
import { User } from '../../models/user';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styles: []
})
export class LoginComponent implements OnInit {
  user: UserLogin;
  ref = '';
  constructor(private authService: AuthService, private router: Router,
                                                    private route: ActivatedRoute) {
    this.user = new UserLogin();
  }

  ngOnInit() {  
    this.route.queryParams.subscribe((params) => {
      this.ref = params.ref;
    });
  }
  Login() {
    this.authService.ValidateUser(this.user).subscribe((res) => {
      const authObj: User = res;
      if (authObj.email !== '') {
        authObj.isAuth = true;
        this.authService.setAuthUser(authObj);
        if (this.ref !== undefined && this.ref !== '') {
          this.router.navigate([this.ref]);
        }
        else {
          if (authObj.roles.indexOf('Admin') > -1) {
            this.router.navigate(['admin']);
          } else {
            this.router.navigate(['user']);
          }
        }
      }
    });
  }
}


4- Creating AppRouting file 

Below is the Code of app.routing.ts file.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AdminAuthGuard, UserAuthGuard } from './services/auth.guard';

const routes: Routes = [
    { path: '', loadChildren: 'app/public/public.module#PublicModule' },
    { path: 'user', loadChildren: 'app/user/user.module#UserModule',
                                                    canActivate:[UserAuthGuard] },
    { path: 'admin', loadChildren: 'app/admin/admin.module#AdminModule',
                                                    canActivate: [AdminAuthGuard] }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
})
export class AppRoutingModule { }


5- Creating Route Guard file 

Below is the code of auth.guard.ts file.

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class AdminAuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) { }
  canActivate() {
    if (!(this.authService.user != null && this.authService.user.isAuth)) {
      this.router.navigate(['login']);
      return false;
    } else if (this.authService.user.roles.indexOf('Admin') > -1) {
      return true;
    } else {
      this.router.navigate(['unauthorize']);
      return false;
    }
  }
}

@Injectable()
export class UserAuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) { }
  canActivate() {
    if (!(this.authService.user != null && this.authService.user.isAuth)) {
      this.router.navigate(['login']);
      return false;
    } else if (this.authService.user.roles.indexOf('User') > -1) {
      return true;
    } else {
      this.router.navigate(['unauthorize']);
      return false;
    }
  }
}

Creating Sign-out feature 

Below is the code snippet from a component.

  ...
    <ul class="nav navbar-nav pull-right" *ngIf="authService.user!=undefined">
      <li style="padding: 15px;">
        Welcome : {{authService.user.name}}
      </li>
      <li>
        <a href="javascript:void(0)" (click)="signout()">SignOut</a>
      </li>
    </ul> ...


  ...       constructor(public authService: AuthService, private router: Router) { }
      signout() {
        this.authService.SignOut();
        this.router.navigate(['/login']);
      }     ...

Sending token value in Request header- 

1- Using Http-Interceptors

2- Using RequestOptions (below is example code snippet)

@Injectable()
export class ProductService {
  private baseUrl = '';
  private headers: any;
  private options;
  constructor(private http: Http, private authService: AuthService) {
    this.options = new RequestOptions({     headers: new Headers({                           'authorization': this.authService.user.token,
                          'Content-Type': 'application/json'
                         })
    });
    this.baseUrl = env.apiAddress;
  }

  getAll(): Observable<Product[]> {
    return this.http.get(`${this.baseUrl}/product`, this.options)
      .map((res: Response) => res.json())
      .catch((error: any) => Observable.throw(error.json().error || 'Server error'));
  }
  add(product: Product): Observable<Response> {
    return this.http
      .post(`${this.baseUrl}/product`, JSON.stringify(product), this.options)
      .catch((error: any) => Observable.throw('Server error'));
  }
    .......         ......


Continue Reading →

Sunday, 22 January 2023

JWT authentication in ASP.NET Core WebAPI

Using JWT (JSON Web Tokens) in a Web API is a common approach for handling authentication and authorization. Here's a concise guide on how to implement JWT in a Web API, typically using a framework like ASP.NET Core, but the principles apply to other frameworks as well.

Step 1: Install Necessary Packages

For ASP.NET Core, you'll need to install the following NuGet packages:

  1. Microsoft.AspNetCore.Authentication.JwtBearer
  2. System.IdentityModel.Tokens.Jwt

Step 2: Configure JWT in Startup

In your Startup.cs file, configure JWT authentication in the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    // Other service configurations...

    var key = Encoding.ASCII.GetBytes("your_secret_key_here"); // Use a strong secret key
    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = false; // Set to true in production
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

    services.AddControllers();
}

Step 3: Create a JWT Token

You'll need a method to generate the JWT. This typically occurs during login:

  public string GenerateJwtToken(string username)
  {
      var claims = new[]
      {
          new Claim(JwtRegisteredClaimNames.Sub, username),
          new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
      };
 
      var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key_here"));
      var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
 
      var token = new JwtSecurityToken(
          issuer: null, // Set if needed
          audience: null, // Set if needed
          claims: claims,
          expires: DateTime.Now.AddMinutes(30),
          signingCredentials: creds);
 
      return new JwtSecurityTokenHandler().WriteToken(token);
  }

Step 4: Secure Your API Endpoints

Use the [Authorize] attribute to protect your API endpoints:

  [Authorize]
  [ApiController]
  [Route("[controller]")]
  public class WeatherForecastController : ControllerBase
  {
      [HttpGet]
      public IActionResult Get()
      {
          return Ok(new { Message = "This is a protected endpoint!" });
      }
  }

Step 5: Handling User Login

Create a login endpoint to authenticate users and return a JWT:

  [HttpPost("login")]
  public IActionResult Login([FromBody] LoginModel login)
  {
      // Validate user credentials (this is just an example)
      if (login.Username == "test" && login.Password == "password") // Replace with actual validation
      {
          var token = GenerateJwtToken(login.Username);
          return Ok(new { Token = token });
      }
 
      return Unauthorized();
  }

Step 6: Testing

Use a tool like Postman to test your endpoints:

  1. Call the login endpoint with valid credentials to receive a JWT.
  2. Use the received token in the Authorization header (Bearer <token>) when accessing protected endpoints.

Where jwt tokens are stored on on server

JWT (JSON Web Tokens) are typically not stored on the server in the same way as session data. Instead, they are often used in a stateless manner, meaning the server does not maintain a session for each user. Here’s how it generally works:

  1. Client-Side Storage: After authentication, the server sends the JWT to the client, which usually stores it in local storage or cookies.

  2. Stateless Authentication: Each time the client makes a request, it sends the JWT along (typically in the Authorization header). The server validates the token without needing to store any session data.

  3. Optional Revocation: If you need to implement token revocation or blacklisting, you might maintain a list of revoked tokens on the server, but this is an additional layer of complexity that somewhat counters the stateless principle.

  4. Expiry: JWTs usually have an expiration time, after which they are considered invalid. This reduces the need for server-side storage since expired tokens can be discarded.

In summary, JWTs are mainly stored client-side, while the server verifies them as needed.

How server verifies jwt token on server

To verify a JWT (JSON Web Token) on the server, the following steps are typically followed:

  1. Extract the Token: The server retrieves the JWT from the request, usually from the Authorization header as a Bearer token.

  2. Decode the Token: The server decodes the JWT to access its header and payload. This step does not require validation and can be done using a base64 decoding method.

  3. Verify the Signature: The most critical part of the verification process is to check the signature of the token:

    • The server uses the algorithm specified in the JWT header (e.g., HS256, RS256) and the secret key (for symmetric algorithms) or the public key (for asymmetric algorithms) that was used to sign the token.
    • It re-generates the signature using the header and payload and compares it with the signature part of the received token.
  4. Check Claims: The server validates the claims in the payload:

    • Expiration: Check the exp claim to see if the token is still valid.
    • Audience: Verify the aud claim to ensure the token was intended for your server.
    • Issuer: Check the iss claim to confirm it was issued by a trusted source.
    • Not Before: Optionally, check the nbf claim to see if the token is being used before its valid time.
  5. Process the Request: If the token is valid and all claims check out, the server processes the request. If not, it responds with an appropriate error (e.g., 401 Unauthorized).

By following these steps, the server ensures that the JWT is valid, has not been tampered with, and is still active.


Reference: https://medium.com/https://www.c-sharpcorner.com/https://javascript.plainenglish.io/

Continue Reading →

Saturday, 21 January 2023

LINQ query related questions

 Find nth max salary using linq

I have a collection of Employee Data. 

//7000,6000,5500,5000
List<Employee> employees = new List<Employee>()
{
new Employee { Id = 1, UserName = "Anil" , Salary = 5000},
new Employee { Id = 2, UserName = "Sunil" , Salary = 6000},
new Employee { Id = 3, UserName = "Lokesh" , Salary = 5500},
new Employee { Id = 4, UserName = "Vinay" , Salary = 7000},
new Employee { Id = 5, UserName = "Vijay" , Salary = 7000},
new Employee { Id = 6, UserName = "vikas" , Salary = 6000}
};

See the below query example. I am finding 2nd max Salary.

Query Example 1:

var employee = Employees.OrderByDescending(e => e.Salary).Skip(1).First();                              

  var result = employees.OrderByDescending(x => x.Salary)
  .Select(x => x.Salary).Distinct().Take(2)
  .Skip(2 - 1).FirstOrDefault();
Console.WriteLine(result);

Query Example 2:

If multiple employees may have equal salary and you wish to return an IEnumerable of all the employees with the second-highest salary you could do:

var result = employees
      .GroupBy(e => e.Salary)
      .OrderByDescending(e=> e.Key)
      .Skip(1)
      .First();
Console.WriteLine(result.Key);


Find 2nd and 3rd max Number from below array using Linq

 int[] numbers = { 1, 4, 2, 6, 3, 7, 9, 0 };

var secondMaxNumber = (from n in numbers orderby n descending select n)
.Take(2).LastOrDefault();
var thirdMaxNumber = (from n in numbers orderby n descending select n).Distinct()
.Skip(2).FirstOrDefault();

Console.WriteLine(secondMaxNumber); //7
Console.WriteLine(thirdMaxNumber);  //6


Continue Reading →

SQL Server Query related questions

1:- Finding nth highest salary in SQL?

Below is the Table structure:

Create table Employees
(
     ID int primary key identity,
     FirstName nvarchar(50),
     LastName nvarchar(50),
     Gender nvarchar(50),
     Salary int
)
GO

Insert into Employees values ('Suraj', 'Kumar', 'Male', 70000)
Insert into Employees values ('Rahul', 'Mad', 'Male', 60000)
Insert into Employees values ('Steve', 'jobs', 'Male', 46000)
Insert into Employees values ('Mahesh', 'kumar', 'Male', 70000)
Insert into Employees values ('Suresh', 'sinha', 'Male', 45000)
Insert into Employees values ('Ravi', 'kukreja', 'Female', 30000)
Insert into Employees values ('Priyanka', 'singh', 'Female', 36000)
Insert into Employees values ('Riya', 'Mishra', 'Male', 90000)
GO

Here we are finding 2nd highest Salary from Employee Table.

Using  Sub-Query with Max function

  Select Max(Salary) from Employee where Salary < (Select Max(Salary) from Employee)

Using  Sub-Query 

  SELECT TOP 1 SALARY
  FROM (
        SELECT DISTINCT TOP 2 SALARY
        FROM EMPLOYEE
        ORDER BY SALARY DESC
        ) RESULT
  ORDER BY SALARY ASC;

Using CTE

  WITH RESULT AS
  (
      SELECT DENSE_RANK() OVER (ORDER BY SALARY DESC) AS DENSERANK, SALARY
      FROM EMPLOYEES
  )
  SELECT TOP 1 SALARY
  FROM RESULT
  WHERE DENSERANK = 2

2:- Delete duplicate rows from table

WITH tblTemp as
(
   SELECT ROW_NUMBER() Over(PARTITION BY NameDepartment ORDER BY Name)
   AS RowNumber, * FROM emp
)
DELETE FROM tblTemp where RowNumber >1



Continue Reading →

Tuesday, 17 January 2023

Understanding dependency injection Angular

 Dependency injection, or DI, is one of the fundamental concepts in Angular. DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.

Two main roles exist in the DI system: dependency consumer and dependency provider.

Angular facilitates the interaction between dependency consumers and dependency providers using an abstraction called Injector. When a dependency is requested, the injector checks its registry to see if there is an instance already available there. If not, a new instance is created and stored in the registry. Angular creates an application-wide injector (also known as "root" injector) during the application bootstrap process, as well as any other injectors as needed. 

Providing dependency

Imagine there is a class called HeroService that needs to act as a dependency in a component.

The first step is to add the @Injectable decorator to show that the class can be injected.

@Injectable()
class HeroService {}

The next step is to make it available in the DI by providing it. A dependency can be provided in multiple places:

At the Component level, using the providers field of the @Component decorator. In this case the HeroService becomes available to all instances of this component and other components and directives used in the template. For example:

  @Component({
    selector: 'hero-list',
    template: '...',
    providers: [HeroService]
  })
  class HeroListComponent {}

When you register a provider at the component level, you get a new instance of the service with each new instance of that component. 

At the NgModule level, using the providers field of the @NgModule decorator. In this scenario, the HeroService is available to all components, directives, and pipes declared in this NgModule. For example:

  @NgModule({
    declarations: [HeroListComponent]
    providers: [HeroService]
  })
  class HeroListModule {}

When you register a provider with a specific NgModule, the same instance of a service is available to all components in that NgModule. 

At the application root level, which allows injecting it into other classes in the application. This can be done by adding the providedIn: 'root' field to the @Injectable decorator:

  @Injectable({
    providedIn: 'root'
  })
  class HeroService {}

When you provide the service at the root level, Angular creates a single, shared instance of the HeroService and injects it into any class that asks for it. 

Injecting a dependency

The most common way to inject a dependency is to declare it in a class constructor. When Angular creates a new instance of a component, directive, or pipe class, it determines which services or other dependencies that class needs by looking at the constructor parameter types. For example, if the HeroListComponent needs the HeroService, the constructor can look like this:

  @Component({ … })
  class HeroListComponent {
    constructor(private service: HeroService) {}
  }

When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn't yet exist, the injector creates one using the registered provider, and adds it to the injector before returning the service to Angular.

When all requested services have been resolved and returned, Angular can call the component's constructor with those services as arguments.


Angular Providers: UseClass, UseValue, UseFactory & UseExisting 

Reference: https://angular.io/

Continue Reading →

Wednesday, 11 January 2023

Improve Performance of Angular app

Improve Performance of Angular app

1: Lazy loading module

The enterprise application built using angular contains many feature modules. All these modules are not required to be loaded at once by the client. With large enterprise applications, the size of the application increases significantly with time, and it also increases the bundle size.

Once the bundle size increases, the performance goes down exponentially because every KB extra on the main bundle contribute to slower:-
  • Download
  • Parsing
  • JS Execution
This can be solved using lazy loading. Lazy Loading is loading only the necessary modules at the initial load. This not only reduces the bundle size but also decreases the load time. Other modules are only loaded when the user navigates to the created routes. This increases the application load time by a great deal.

2: Pure Pipes

In Angular, pipes transform the data to a different format. E.g., the:- 'date | short date converts the date to a shorter format like 'dd/MM/yyyy.' Pipes are divided into two categories:-
  • Impure pipe
  • Pure Pipe
The impure pipe is those pipes that produce different results for the same input over time. The pure pipes are the pipes that produce the same result for the same input. 

3: use AOT compilation

As we know that Angular provides two types of compilation:-
  • JIT(Just-in-time)
  • AoT(Ahead-of-time)
Afterward 8 version, Angular provides the AoT compilation by default, which increases the performance. Because the JIT compiles the application in the runtime. Also, the JIT compilation bundles the compiler with itself, which increases the size of the bundler. Also, it increases the rendering time of the component.

But with the AoT compilation, compiles the application in the build time, produces only the compiled templates, and doesn't include the compiler. So, the bundle size decreases, and rendering time increases significantly. So, We should always use AoT compilation for our applications.

4: Remove Unnecessary Imports and packages from projects.

5: Unsubscribe the Observable after rendering the content Click here to learn how to UnSubscribe

6: Use trackBy option for *ngFor directive 

7: Cache static content using Angular Progressive Web App (PWA)
Caching the static content will make your Angular app load faster as it will already be in the browser. This is easily done using Angular PWA which will use service workers to cache the static content, that is the js, css bundles, images and static served files, and present them without making a call to the server.

8: OnPush change detection
The default change detection behavior for components is to re-render every time an asynchronous event has happened in the app such as click, XMLHttpRequest, setTimout. This can become a problem because this will cause many unnecessary renderings of the templates, that may not have been changed

OnPush change detection fixes this by only re-rendering a template if either:

One of its input properties has gotten a new reference
An event from the component or one of its children eg. click on a button in the component
Explicit run of change detection
To apply this strategy you just need to set the change-detection strategy in the component’s decorator:

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styles: [],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class LoginComponent implements OnInit {

}

9: Preloading Strategies 
There are two types of preloading mechanisms.

Preloading modules — Loading modules asynchronously in the background is called preloading modules. This technique should be used with lazy loading.
@NgModule({
    imports: [RouterModule.forRoot(routes, {preloadingStrategy : PreloadAllModules})],
    exports: [RouterModule],
})
export class AppRoutingModule { }

Preloading in Angular means loading the Lazy loaded Modules in the background asynchronously, while user is interacting with the app. This will help boost up the loading time of the app. 
    By Preloading the lazy loaded module, the user do not have to wait for the module to be downloaded as the module is already downloaded in the background.

Preloading component data —Using resolvers for the routes to block a component from rendering until the data is available.

Continue Reading →

Wednesday, 4 January 2023

Sessions and Caching In ASP.NET Core

 How To Use Sessions In ASP.NET Core

1- We need to install the stable version of “Microsoft.AspNetCore.Session” from the NuGet Package Manager. Then only we can access the session state in ASP.NET Core.

2- Now, open the ”Startup.cs” to configure the services.  we need to add the session service to the container so that we can add the services in the “ConfigureServices” function.

public void ConfigureServices(IServiceCollection services)  
{
    services.AddDistributedMemoryCache();  
    services.AddSession(options => {  
        options.IdleTimeout = TimeSpan.FromMinutes(1); //Set Time  
    });  
    services.AddMvc();  
}

3- Configure the HTTP Request Pipeline

Now, in the same class, we add “app.UseSession()” inside the “Configure” function so that it gets called by the runtime.

app.UseSession();

Now we are ok to use session in our application. See the below code for session.

public class HomeController : Controller  
{  
    const string SessionName = "_Name";  
    const string SessionAge = "_Age";  
    public IActionResult Index()  
    {  
        HttpContext.Session.SetString(SessionName, "Jarvik");  
        HttpContext.Session.SetInt32(SessionAge, 24);  
        return View();  
    }  

    public IActionResult About()  
    {  
        ViewBag.Name = HttpContext.Session.GetString(SessionName);  
        ViewBag.Age = HttpContext.Session.GetInt32(SessionAge);  
        ViewData["Message"] = "Asp.Net Core !!!.";  

        return View();  
    }  
}

Cache in ASP.NET Core

ASP.NET Core supports several different caches. The simplest cache is based on the IMemoryCache. IMemoryCache represents a cache stored in the memory of the web server. Apps running on a server farm (multiple servers) should ensure sessions are sticky when using the in-memory cache. Sticky sessions ensure that requests from a client all go to the same server. 

Non-sticky sessions in a web farm require a distributed cache to avoid cache consistency problems. 

The in-memory cache can store any object. The distributed cache interface is limited to byte[]. The in-memory and distributed cache store cache items as key-value pairs.

Types of Caching in Dotnet Core: 

The lowest level of caching in ASP.NET Core that we are going to discuss is the caching of data using IMemoryCache and IDistributedCache. These interfaces are the standard, in-built mechanisms for caching data in .NET Core. All other techniques that we discuss later in the article rely on IMemoryCache or IDistributedCache internally.

IMemoryCache: IMemoryCache is very similar to the System.Runtime.Caching.MemoryCache cache from .NET 4.

You can register IMemoryCache in ConfigureServices using:

services.AddMemoryCache();

//services.AddDistributedMemoryCache();
//services.AddResponseCaching();

Implementing MemoryCache in Code.

public class BlahService
{
    private const string BlahCacheKey = "blah-cache-key";
    private readonly IMemoryCache _cache;

    public BlahService(IMemoryCache cache, IDatabase db)
    {
        _cache = cache;
    }
   
    public async Task<IEnumerable<Blah>> GetBlahs()
    {
        blahs = await _db.getAll<Blah>(...);
        _cache.Set(BlahCacheKey, blahs, ...);
        return blahs;
    }
}

When saving to IMemoryCache, MemoryCacheEntryOptions provides you with many ways to expire cache content. 

//absolute expiration using TimeSpan
_cache.Set("key", item, TimeSpan.FromDays(1));

//absolute expiration using DateTime
_cache.Set("key", item, new DateTime(2020, 1, 1));

//sliding expiration (evict if not accessed for 7 days)
_cache.Set("key", item, new MemoryCacheEntryOptions
{
    SlidingExpiration = TimeSpan.FromDays(7)
});

Learn more about Memory Cache https://learn.microsoft.com

IDistributedCache A distributed cache is a cache shared by multiple app servers, typically maintained as an
external service to the app servers that access it. A distributed cache can improve the performance
and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service
or a server farm.
A distributed cache has several advantages over other caching scenarios where cached data is
stored on individual app servers.
When cached data is distributed, the data:
  1. Is coherent (consistent) across requests to multiple servers.
  2. Survives server restarts and app deployments.
  3. Doesn't use local memory.
Distributed cache configuration is implementation specific. This article describes how to configure
SQL Server and Redis distributed caches. Third party implementations are also available, such as
NCache (NCache on GitHub). Regardless of which implementation is selected, the app interacts with
the cache using the IDistributedCache interface.

Learn More about distributed cache


Continue Reading →

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (47) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (49) CD (1) CI (2) CloudComputing (2) Coding (8) CQRS (1) CSS (2) Design_Pattern (7) DevOps (4) DI (3) Dotnet (10) DotnetCore (19) Entity Framework (4) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (10) microservice (4) Mongodb (1) MVC (46) NodeJS (8) React (10) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (3) UI (1) UnitTest (2) WCF (14) Web Api (16) Web Service (1) XMl (1)

Dotnet Guru Archives