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

Repository