Introduction
In this article we will learn about how to create Clean Architecture in ASP.NET Core Web API With JWT JWT Authentication . We can better understand this step by step
Step 1: Create a Folder with project name
Step 2: To open folder In VStudio 2022
Step 3: Create a new Project in same project folder
Step 4: Select .Net Core Web API
Step 5: Select the Current Version of .Net 6.0 and select the path of the created folder
Step 6: Web API Project is created
Step 7: Right Click on Solution Explorer then add c# class library with the name of project.App
Step 8: Right Click on Solution Explorer then add c# class library with the name of project.Core
Step 9: Right Click on Solution Explorer then add c# class library with the name of project.Infra
Step 10: Right Click on project.WebApp and select add => project reference => Reference Manager Popup select project.Infra then click OK
Step 11: Right Click on project.Infra and select add => project reference => Reference Manager Popup select project.App and project.Core then click Ok
Step 12: Now right click on project.infra and rename default class1.cs to DependencyInjection and make that class static
Step 13: Now add Dependency via Suggestion(Select latest suggestion)
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration Configuration)
{
return services;
}
Step 14: Expand project.Core then Right Click on Dependencies and install the following packages
- Microsoft.EntityFrameworkCore 6.0.10
- Microsoft.EntityFrameworkCore.SqlServer 6.0.10
- Microsoft.EntityFrameworkCore.Design 6.0.10
- Microsoft.EntityFrameworkCore.Tools 6.0.10
Step 15: Right Click on project.Infra and Add a folder named Services
Step 16: Now Do Scaffold connection as per your DB name (select package source= all and default project= project.core )
Step 17: Add nuget package: Microsoft.EntityFrameworkCore.Tools in project.webApp
Step 18: Create at least one table in database Example UserAdmin
Step 19: Apply below command in Package Manager Console. (select package source= all and default project= project.core )
=>Scaffold-DbContext "Server=NameServer\MSSQLSERVER01;Database=AllFoldNew;Trusted_Connection=True;"
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
Step 20: Go To appsettings.json and add ConnectionString for connection of project with database below AllowedHosts
"ConnectionStrings": {
"con": "Server=NameServer\\MSSQLSERVER01;Database=AllFoldNew;Trusted_Connection=True;"
}
Step 21: In Service folder create UserAdmin Folder => In UserAdmin Folder => Create Files
- Interface files (IUserAdminServices.cs)
- Class files (UserAdminServices.cs)
1. Interface internal replace with public Like
public interface IUserAdminServices
{
}
2. class file implement interface and create dbcontext object and add constructor (add reference as per suggestion) like
namespace WebAPI_Structure.Infra.Services.UserAdmin
{
public class UserAdminServices : IUserAdminServices
{
private readonly DemoDBContext _context;
public UserAdminServices(DemoDBContext context)
{
_context = context;
}
}
}
3. add service in dependency injection
services.AddTransient<IUserAdminServices, UserAdminServices>();
Note: DBContext name as per your databasecontext name
Step 22: Now add one table in database like say product (productid, product name) Update our database model so execute below command
When a database is updated or added in sql server then scaffolding is needed in .net (Entities is folder name which contains tables )
(Scaffold-DbContext "Server=servername;Database=DemoDB;User ID=username;password=password;MultipleActiveResultSets=true;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Entities -force) - (Remote Command)
Scaffold-DbContext "Server=servername;Database=DemoDB;Trusted_Connection=True; "Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -force - ( Local Command)
Step 23: In Service folder create Product Folder => In Product Folder => Create Files
- Interface files (IProductServices)
- Class files (ProductServices)
Step 24: Right Click on project.WebApp and select controller
Step 25: In a Controller select API (Empty Controller) and give a name
Step 26: Implement IproductService in ProductService (add reference as per suggestion)
ProductService.cs
public class ProductServices : IProductServices
{
private readonly AllFoldNewContext _context;
public ProductServices(AllFoldNewContext context)
{
_context = context;
}
}
Step 27: project.webapp - inside properties inside controller Right Click on Controller Foler and Select API and select API Controller-Empty Click on Add and give named ProductController then Okay
Step 28: Create Interface Object in a Product Controller
private readonly IProductServices _productServices;
Step 29: Create Constructor for ProductControlller
public ProductController(IProductServices productServices)
{
_productServices = productServices;
}
Step 30: Right Click on project.App and create DTO folder and inside it create DTO class named ProductDTO(replace internal to public)
Step 31: Add Your class properties as per your requirement.
Step 32: Create one method in IProductServices
Task<dynamic> GetAllProduct();
Step 33: Create one method in ProductService and import missing package
async Task<dynamic> IProductServices.GetAllProduct()
{
return await _context.Products.Select(x => new ProductDTO { ProductId = x.ProductId }).ToListAsync();
//return null;
}
//using AllFold.Core.Entities;
//using Microsoft.EntityFrameworkCore;
Step 34: Create one web API method in productController
[HttpGet("GetProduct")]
public async Task<IActionResult> GetProduct()
{
try
{
var data = await _productServices.GetAllProduct();
if (data.Count != 0)
{
return Ok(data);
}
else
{
return Ok("null");
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
Step 35: project.webapp - Add code in program.cs
builder.Services.AddControllers(); //after this line
builder.Services.AddInfrastructure(builder.Configuration);
Step 36: Add Services inside project.infra in AddInfrastructure() method
services.AddSqlServer<AllFoldNewContext>(Configuration.GetConnectionString("ConnectionStrings"));
services.AddTransient<IProductServices, ProductServices>();
Step 37: Now run project, and display error like
Step 38: Open launchSettings.json and replace HTTPS to HTTP in applicationUrl
"applicationUrl": "https://localhost:7074;http://localhost:5074", replace below line
"applicationUrl": "http://localhost:7074;http://localhost:5074",
And now run the application. All product is showing
Step 39: Now implement Login API
1. First of all Create Login API. Create AdminUserController in Controller folder
Declare Database Context object, UserAdmin Interface object, and IConfiguration object to represent key/value properties.
private readonly DemoDBContext _context;
private readonly IUserAdminServices _useradminServices;
private readonly IConfiguration _configuration;
2. Create Constructor and initialise all object
public AdminUserController(IUserAdminServices useradminServices, IConfiguration configuration, DemoDBContext context)
{
_useradminServices = useradminServices;
_configuration = configuration;
_context = context;
}
3. Create DTO for UserAdminDTO
4. Create Login API like
5. Login is working
Step 40: now implement JWT Token
1. first install project.webapp JWT Package
Microsoft.AspNetCore.Authentication.JwtBearer version is 6.0.10
2. Modify Login API Code and add the following namespace in the controller
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
3. project.infra - add dependency BCrypt
4. Define Token in app-setting.json
"AppSettings": {
"Token": "My Top Secret Key"
},
5. Now run API enter correct user email and password, output like
Step 41: Now moving to all API access after token is verified so I have added [Authorize] action filter above API ActionMethod and try to access API and see the error as response like
Step 42: program.cs file - comment AddSwaggerGen() function and add below code
Step 43: Run the app. Authorized and try to access but still does not work giving error like
Step 44
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Adding Jwt Bearer
.AddJwtBearer(options => {
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false,
ValidateAudience = false,
ValidAudience = "https://localhost:44324",
ValidIssuer = "https://localhost:44324",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["AppSettings:Token"])),
ClockSkew = TimeSpan.Zero
};
});
add reference as per suggestion. Import and now run app and try to directly access API, give error 401
Error: Unauthorized
So first of all login with correct username and password and authorized with token and access the API to get data
see screen Step by Step
- we have direct access getall product API - Error: Unauthorized
- now login with correct email and password generated token verify with bearer token
- Try to access API, still give error Error: Unauthorized
- program.cs file - add UseAuthentication() function
app.UseAuthentication();
- run app and get all product
Conclusion
ASP.Net Core Clean Architecture to create web API with different project and module sepration to access data and generate API with JWT Token integration.
Enjoy Coding !!!!
We have got the response. Fantastic! The ASP.Net Core Clean Architecture is working as expected.
Thank you for reading my article. Please leave your comments in the comment box below.