How to Build Enterprise .Net Core Web API 6
Initial Setup
Applications
- Microsoft Visual Studio 2022
- GitHub
- Postman
- Datalust Seq
- Microsoft SQL Server 2019 Express Edition
- Microsoft SQL Server Management Studio (SSMS) with Azure Data Studio
Services
CORS
Under the Program.cs add the additional services for Cors:
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll",
b => b.AllowAnyHeader()
.AllowAnyOrigin()
.AllowAnyMethod());
});
Serilog
Under Manage NuGet packages, installed:
- Serilog.AspNetCore by Microsoft, Serilog Contributors
- Serilog.Expressions by Serilog Contributors
- Serilog.Sinks.Seq by Serilog Contributors
Under the Program.cs add the additional services for Serilog:
builder.Host.UseSerilog((ctx, lc) => lc.WriteTo.Console().ReadFrom.Configuration(ctx.Configuration));
Under the appSettings.json, change to:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "./logs/log-.txt",
"rollingInterval": "Day"
}
},
{
"Name": "Seq",
"Args": { "serverUrl": "http://localhost:5341" }
}
]
},
"AllowedHosts": "*"
}
EntityFramework
Under Manage NuGet packages, installed:
- EntityFramework Core SQL Server by Microsoft
- EntityFramework Core Tools by Microsoft
Under the appSettings.json, add to:
"ConnectionStrings": {
"HotelListingDbConnectionString": "Server=DCAUSYD050\\SQLEXPRESS;Database=HotelListingDb;Trusted_Connection=True;MultipleActiveResultSets=True"
},
Under the Program.cs add the additional services for Serilog:
var connectionString = builder.Configuration.GetConnectionString("HotelListingDbConnectionString");
builder.Services.AddDbContext<HotelListingDbContext>(options =>
{
options.UseSqlServer(connectionString);
});
Create a HotelListingDbContext class:
using Microsoft.EntityFrameworkCore;
namespace HotelListing.API.Data
{
public class HotelListingDbContext : DbContext
{
public HotelListingDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<Hotel> Hotels { get; set; }
public DbSet<Country> Countries { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Country>().HasData(
new Country
{
Id = 1,
Name = "Australia",
ShortName = "AU"
},
new Country
{
Id = 2,
Name = "New Zealand",
ShortName = "NZ"
},
new Country
{
Id = 3,
Name = "Indonesia",
ShortName = "ID"
}
);
modelBuilder.Entity<Hotel>().HasData(
new Hotel
{
Id = 1,
Name = "Australia Hotel",
Address = "Sydney",
CountryId = 1,
Rating = 4.5
},
new Hotel
{
Id = 2,
Name = "NZ Motel",
Address = "Chrischurch",
CountryId = 2,
Rating = 4.3
},
new Hotel
{
Id = 3,
Name = "Indo Hotel",
Address = "Bali",
CountryId = 3,
Rating = 4
}
);
}
}
}
Create a Country model:
namespace HotelListing.API.Data
{
public class Country
{
public int Id { get; set; }
public string Name { get; set; }
public string ShortName { get; set; }
public virtual IList<Hotel> Hotels { get; set; }
}
}
Create a Hotel model:
using System.ComponentModel.DataAnnotations.Schema;
namespace HotelListing.API.Data
{
public class Hotel
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public double Rating { get; set; }
[ForeignKey(nameof(CountryId))]
public int CountryId { get; set; }
public Country Country { get; set; }
}
}
Data Transfer Object (DTO)
This abstraction of the model object is a view model approach, which aims to prevent the overposting attack.
AutoMapper
Under Manage NuGet packages, installed:
- AutoMapper Extensions Microsoft Dependency Injection by Jimmy Bogard
Credits
Photo by Pixabay: https://www.pexels.com/photo/apple-laptop-notebook-office-39284/