@manhng

Welcome to my blog!

Migration to ASP.NET Core in .NET 6

October 14, 2021 09:21

Migration to ASP.NET Core in .NET 6 (edit)

Migration to ASP.NET Core in .NET 6

.NET 6 ASP.NET Core Migration (github.com)

Maybe it's time to rethink our project structure with .NET 6

Maybe it's time to rethink our project structure with .NET 6 - Tim Deschryver

Implementing a microservice domain model with .NET

Implementing a microservice domain model with .NET | Microsoft Docs

The simplicity of ASP.NET Endpoints

The simplicity of ASP.NET Endpoints - Tim Deschryver

These new routing APIs have far less overhead than controller-based APIs. Using the new routing APIs, ASP.NET Core is able to achieve ~800k RPS in the TechEmpower JSON benchmark vs ~500k RPS for MVC.

Minimal APIs at a glance (.NET 6)

Minimal APIs at a glance (github.com)

Migration to ASP.NET Core in .NET 6

WebApplication and WebApplicationBuilder

.NET 6 introduces a new hosting model for ASP.NET Core applications. This model is streamlined and reduces the amount of boilerplate code required to get a basic ASP.NET Core application up and running.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World");

app.Run();

This model unifies Startup.cs and Program.cs into a single file experience that takes advantage of top level statements to remove any boilerplate. There should be a mostly mechanical translation from .NET 5 projects using a Startup class to the new hosting model:

Program.cs (.NET 5)

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Startup.cs (.NET 5)

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.MapRazorPages();
    }
}

Program.cs (.NET 6)

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

The above shows that ConfigureServices(IServiceCollection) can be configured using WebApplicationBuilder.Services and Configure(IApplicationBuilder...) can be configured by using WebApplication.

Differences in the hosting model

  • The developer exception page middleware is enabled when the environment is Development.

  • The application name always defaults to the entry point assembly's name Assembly.GetEntryAssembly().GetName().FullName. When using the WebApplicationBuilder in a library, you will need to explicitly change the application name to the library's assembly to allow MVC's application part discovery to work (finding controllers, views etc) (see the Cheatsheet for instructions on how to do this).

  • The endpoint routing middleware wraps the entire middleware pipeline. This means there's no need to have explicit calls to UseEndpoints to register routes. UseRouting can still be used to move where route matching happens.

  • The final pipeline is created before any IStartupFilter runs. This means that exceptions caused while building the main pipeline won't be visible to the IStartupFilter call chain.

  • Some tools (like EF migrations) use Program.CreateHostBuilder to access the application's IServiceProvider to execute custom logic in the context of the application, these tools have been updated to use a new technique to achieve the same thing. We will work with the ecosystem to make sure tools are all updated to use the new model.

  • It is not possible to change any host settings (application name, environment or the content root) after the creation of the WebApplicationBuilder (see the Cheatsheet for instructions on how to do this). The following APIs will throw an exception:

    WebHost

    builder.WebHost.UseContentRoot(Directory.GetCurrentDirectory());
    builder.WebHost.UseEnvironment(Environments.Staging);
    
    builder.WebHost.UseSetting(WebHostDefaults.ApplicationKey, "ApplicationName2");
    builder.WebHost.UseSetting(WebHostDefaults.ContentRootKey, Directory.GetCurrentDirectory());
    builder.WebHost.UseSetting(WebHostDefaults.EnvironmentKey, Environments.Staging);

    Host

    builder.Host.UseEnvironment(Environments.Staging);
    builder.Host.UseContentRoot(Directory.GetCurrentDirectory());
  • It is not possible to use the Startup class via the WebApplicationBuilder.Host or WebApplicationBuilder.WebHost. The following will throw an exception:

    var builder = WebApplication.CreateBuilder(args);
    builder.Host.ConfigureWebHostDefaults(webHostBuilder =>
    {
        webHostBuilder.UseStartup<Startup>();
    });

    OR

    var builder = WebApplication.CreateBuilder(args);
    builder.WebHost.UseStartup<Startup>();
  • The IHostBuilder implementation on WebApplicationBuilder (WebApplicationBuilder.Host), does not defer execution of ConfigureServices, ConfigureAppConfiguration or ConfigureHostConfiguration methods. This allows code using WebApplicationBuilder to observe changes made to the IServiceCollection and IConfiguration. The below example will only add Service1 as an IService.

    using Microsoft.Extensions.DependencyInjection.Extensions;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Host.ConfigureServices(services =>
    {
        services.TryAddSingleton<IService, Service1>();
    });
    
    builder.Services.TryAddSingleton<IService, Service2>();
    
    var app = builder.Build();
    
    // This will print Service1
    Console.WriteLine(app.Services.GetRequiredService<IService>());
    
    app.Run();
    
    class Service1 : IService
    {
    
    }
    
    class Service2 : IService
    {
    
    }
    
    interface IService
    {
    
    }

Building libraries for ASP.NET Core

The existing .NET ecosystem has built extensibility around IServiceCollection, IHostBuilder and IWebHostBuilder. These properties are available on the WebApplicationBuilder as Services, Host and WebHost.

The WebApplication implements both Microsoft.AspNetCore.Builder.IApplicationBuilder and Microsoft.AspNetCore.Routing.IEndpointRouteBuilder.

We expect library authors to continue targeting IHostBuilder, IWebHostBuilder, IApplicationBuilder and IEndpointRouteBuilder when building ASP.NET Core specific components. This will ensure that your middleware, route handler, or other extensibility points continue to work across different hosting models.

FAQ

Is the new hosting model less capable

No, it should be functionally equivalent for 98% to what you can do with the IHostBuilder and the IWebHostBuilder. There are more advanced scenarios (the 2%) that will require specific knobs on IHostBuilder but we expect those to be extremely rare.

Is the generic hosting model dead/deprecated?

No, it's not. It's an alternative model that will keep working forever. The generic host still underpins the new hosting model and is still the primary way to host worker-based applications.

Do I have to migrate to the new hosting model

No, you don't have to. It's the preferred way to host ASP.NET Core applications from .NET 6 and onwards but you aren't forced to change your project layout. This means you can upgrade from .NET 5 to .NET 6.0 by changing the target framework in your project file from net5.0 to net6.0.

Do I have to use top-level statements?

The new project templates all use top-level statements, but these new hosting APIs can be used in any .NET 6 application to host a webserver/web application.

Where do I put state that was stored as fields in my Program/Startup class?

There are 2 solutions to this problem:

  1. You can store the state on another class. Assuming this was static state that you were accessing from anywhere in the application.
  2. There's a Program class generated by top level statements that you can put this state on if you wish to keep that semantic.

This is an example of #2:

.NET 5

public class Startup
{
    public static string ConfigurationValue { get; private set; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

        ConfigurationValue = Configuration["SomeValue"];
    }

    public IConfiguration Configuration { get; }

    // More configuration here
}

.NET 6

var builder = WebApplication.CreateBuilder(args);

ConfigurationValue = builder.Configuration["SomeValue"];

var app = builder.Build();

app.Run();

partial class Program
{
    public static string ConfigurationValue { get; private set; }
}

This would make it possible to use Program.ConfigurationValue in your .NET 6 application.

NOTE: We recommend using dependency injection to flow state in your ASP.NET Core applications.

Does WebApplicationFactory/TestServer still work?

WebApplicationFactory<TEntryPoint> is the way to test the new hosting model. See the Cheatsheet for an example.

What if I was using a custom dependency injection container?

This is still supported, see the Cheatsheet for an example.

I like the Startup class; can I keep it?

Yes, you can. Here's a shim you can use to keep it working as is with the new hosting model:

Program.cs

var builder = WebApplication.CreateBuilder(args);

var startup = new Startup(builder.Configuration);

startup.ConfigureServices(builder.Services);

// Uncomment if using a custom DI container
// builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// builder.Host.ConfigureContainer<ContainerBuilder>(startup.ConfigureContainer);

var app = builder.Build();

startup.Configure(app, app.Environment);

app.Run();

Startup.cs

class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {

    }

//  Uncomment if using a custom DI container
//  public void ConfigureContainer(ContainerBuilder builder)
//  {
//  }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment environment)
    {

    }
}

There are a few differences here:

  • You control the instantiation and lifetime of the Startup class.
  • Any additional services injected into the Configure method need to be manually resolved by your Program class.

Cheatsheet

Adding middleware

.NET 5

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseStaticFiles();
    }
}

.NET 6

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.UseStaticFiles();

app.Run();

Adding routes

.NET 5

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/", () => "Hello World");
        });
    }
}

.NET 6

In .NET 6, routes can be added directly to the WebApplication without an explicit call to UseEndpoints.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () => "Hello World");

app.Run();

NOTE: Routes added directly to the WebApplication will execute at the end of the pipeline.

Changing the content root, application name and environment

.NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseEnvironment(Environments.Staging)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>()
                      .UseSetting(WebHostDefaults.ApplicationKey, typeof(Program).Assembly.FullName);
        });

.NET 6

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    ApplicationName = typeof(Program).Assembly.FullName,
    ContentRootPath = Directory.GetCurrentDirectory(),
    EnvironmentName = Environments.Staging
});

Console.WriteLine($"Application Name: {builder.Environment.ApplicationName}");
Console.WriteLine($"Environment Name: {builder.Environment.EnvironmentName}");
Console.WriteLine($"ContentRoot Path: {builder.Environment.ContentRootPath}");

var app = builder.Build();

Adding configuration providers

.NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(config =>
        {
            config.AddIniFile("appsettings.ini");
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

.NET 6

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddIniFile("appsettings.ini");

var app = builder.Build();

Adding logging providers

.NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.AddJsonConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

.NET 6

var builder = WebApplication.CreateBuilder(args);

// Configure JSON logging to the console
builder.Logging.AddJsonConsole();

var app = builder.Build();

Adding services

.NET 5

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add the memory cache services
        services.AddMemoryCache();

        // Add a custom scoped service
        services.AddScoped<ITodoRepository, TodoRepository>();
    }
}

.NET 6

var builder = WebApplication.CreateBuilder(args);

// Add the memory cache services
builder.Services.AddMemoryCache();

// Add a custom scoped service
builder.Services.AddScoped<ITodoRepository, TodoRepository>();

var app = builder.Build();

Customizing the IHostBuilder

.NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Existing extension methods on IHostBuilder can be accessed using the Host property.

.NET 6

var builder = WebApplication.CreateBuilder(args);

// Wait 30 seconds for graceful shutdown
builder.Host.ConfigureHostOptions(o => o.ShutdownTimeout = TimeSpan.FromSeconds(30));

var app = builder.Build();

Customizing the IWebHostBuilder

.NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            // Change the HTTP server implemenation to be HTTP.sys based
            webBuilder.UseHttpSys()
                      .UseStartup<Startup>();
        });

.NET 6

Existing extension methods on IWebHostBuilder can be accessed using the WebHost property.

var builder = WebApplication.CreateBuilder(args);

// Change the HTTP server implemenation to be HTTP.sys based
builder.WebHost.UseHttpSys();

var app = builder.Build();

Changing the web root

By default, the web root is relative to the content root in the wwwroot folder. This is where the static files middleware expects to find static files. You can change this by using the UseWebRoot method on the WebHost property:

.NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            // Look for static files in webroot
            webBuilder.UseWebRoot("webroot")
                      .UseStartup<Startup>();
        });

.NET 6

var builder = WebApplication.CreateBuilder(args);

// Look for static files in webroot
builder.WebHost.UseWebRoot("webroot");

var app = builder.Build();

Custom dependency injection container

This example uses Autofac

.NET 5

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
public class Startup
{
    public void ConfigureContainer(ContainerBuilder containerBuilder)
    {
    }
}

.NET 6

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

// Register your own things directly with Autofac here. Don't
// call builder.Populate(), that happens in AutofacServiceProviderFactory
// for you.
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new MyApplicationModule()));

var app = builder.Build();

Accessing additional services

.NET 5

In Startup.Configure you can inject any service added via the IServiceCollection.

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IService, Service>();
    }

    // Anything added to the service collection can be injected into Configure
    public void Configure(IApplicationBuilder app, 
                          IWebHostEnvironment env,
                          IHostApplicationLifetime lifetime,
                          IService service,
                          ILogger<Startup> logger)
    {
        lifetime.ApplicationStarted.Register(() => 
            logger.LogInformation($"The application {env.ApplicationName} started in we injected {service}"));
    }
}

.NET 6

In .NET 6, there are a few common services available as top level properties on WebApplication and additional services need to be manually resolved from the IServiceProvider via WebApplication.Services.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IService, Service>();

var app = builder.Build();

IService service = app.Services.GetRequiredService<IService>();
ILogger logger = app.Logger;
IHostApplicationLifetime lifetime = app.Lifetime;
IWebHostEnvironment env = app.Environment;

lifetime.ApplicationStarted.Register(() =>
    logger.LogInformation($"The application {env.ApplicationName} started in we injected {service}"));

app.Run();

Testing with WebApplicationFactory/TestServer

In the below samples, the test project uses TestServer and WebApplicationFactory. These ship as separate packages that need to explicit referenced:

WebApplicationFactory

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="{Version}" />
</ItemGroup>

TestServer

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="{Version}" />
</ItemGroup>

This sample is using xUnit and IHelloService will be shared between both examples:

public interface IHelloService
{
    string HelloMessage { get; }
}

public class HelloService : IHelloService
{
    public string HelloMessage => "Hello World";
}

.NET 5

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHelloService, HelloService>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHelloService helloService)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/", async context =>
            {
                await context.Response.WriteAsync(helloService.HelloMessage);
            });
        });
    }
}

With TestServer

[Fact]
public async Task HelloWorld()
{
    using var host = Host.CreateDefaultBuilder()
        .ConfigureWebHostDefaults(builder =>
        {
            // Use the test server and point to the application's startup
            builder.UseTestServer()
                    .UseStartup<WebApplication1.Startup>();
        })
        .ConfigureServices(services =>
        {
            // Replace the service
            services.AddSingleton<IHelloService, MockHelloService>();
        })
        .Build();

    await host.StartAsync();

    var client = host.GetTestClient();

    var response = await client.GetStringAsync("/");

    Assert.Equal("Test Hello", response);
}

class MockHelloService : IHelloService
{
    public string HelloMessage => "Test Hello";
}

With WebApplicationFactory

[Fact]
public async Task HelloWorld()
{
    var application = new WebApplicationFactory<Program>()
        .WithWebHostBuilder(builder =>
        {
            builder.ConfigureServices(services =>
            {
                services.AddSingleton<IHelloService, MockHelloService>();
            });
        });

    var client = application.CreateClient();

    var response = await client.GetStringAsync("/");

    Assert.Equal("Test Hello", response);
}

class MockHelloService : IHelloService
{
    public string HelloMessage => "Test Hello";
}

.NET 6

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IHelloService, HelloService>();

var app = builder.Build();

var helloService = app.Services.GetRequiredService<IHelloService>();

app.MapGet("/", async context =>
{
    await context.Response.WriteAsync(helloService.HelloMessage);
});

app.Run();

In .NET 6, WebApplicationFactory<TEntryPoint> is used to test application using new hosting model. The compiler produces an internal Program class applications that use top level statements. We need to make this available to the test project by using InternalsVisibleTo. This can be done using the project file or in any other .cs file:

MyProject.csproj

<ItemGroup>
    <InternalsVisibleTo Include="MyTestProject" />
</ItemGroup>

OR

[assembly: InternalsVisibleTo("MyTestProject")]

The other solution is to make the Program class public. You can do this with top level statements by defining a public partial Program class anywhere in the project (or in Program.cs):

Program.cs

var builder = WebApplication.CreateBuilder(args);

// ... Wire up services and routes etc

app.Run();

public partial class Program { }
[Fact]
public async Task HelloWorld()
{
    var application = new WebApplicationFactory<Program>()
        .WithWebHostBuilder(builder =>
        {
            builder.ConfigureServices(services =>
            {
                services.AddSingleton<IHelloService, MockHelloService>();
            });
        });

    var client = application.CreateClient();

    var response = await client.GetStringAsync("/");

    Assert.Equal("Test Hello", response);
}

class MockHelloService : IHelloService
{
    public string HelloMessage => "Test Hello";
}

The .NET 5 version and .NET 6 version with the WebApplicationFactory are identical. This is by design.

Stargazers · .NET6Migration.md (github.com)

.NET 6 ASP.NET Core Migration (github.com)

ASP.NET Core Microservices

October 4, 2021 12:05

ASP.NET Core Microservices (edit)

  • Building Microservices on .NET Ecosystem
  • Microservices on .NET platforms

Phần 1: Microservices

Building Microservices on .NET Ecosystem

sanjyotagureddy/aspnetrun-microservices: Building Microservices on .Net Ecosystem (github.com)

Microservices on .NET platforms

aspnetrun/run-aspnetcore-microservices: Microservices on .Net platforms which used Asp.Net Web API, Docker, RabbitMQ, MassTransit, Grpc, Ocelot API Gateway, MongoDB, Redis, PostgreSQL, SqlServer, Dapper, Entity Framework Core, CQRS and Clean Architecture implementation. Also includes Cross-Cutting concerns like Implementing Centralized Distributed Logging with Elasticsearch, Kibana and SeriLog, use the HealthChecks with Watchdog, Implement Retry and Circuit Breaker patterns with Polly and so on.. See Microservices Architecture and Step by Step Implementation on .NET Course w/ discount-> (github.com)

microservices_remastered

GitHub .NET Repos to Take Your Tech Skills to the next level

1) Examples and Tutorials of Event Sourcing in .NET

oskardudycz/EventSourcing.NetCore: Examples and Tutorials of Event Sourcing in .NET (github.com)

2) Full Modular Monolith application with Domain-Driven Design approach

kgrzybek/modular-monolith-with-ddd: Full Modular Monolith application with Domain-Driven Design approach. (github.com)

3) Sample .NET Core REST API CQRS implementation with raw SQL and DDD using Clean Architecture

kgrzybek/sample-dotnet-core-cqrs-api: Sample .NET Core REST API CQRS implementation with raw SQL and DDD using Clean Architecture. (github.com)

4) Clean Architecture with .NET5, C#9 and React+Redux. Use cases as central organizing structure, completely testable, decoupled from frameworks

ivanpaulovich/clean-architecture-manga: Clean Architecture with .NET5, C#9 and React+Redux. Use cases as central organizing structure, completely testable, decoupled from frameworks (github.com)

5) WhiteApp API solution template which is built on Onion Architecture with all essential feature using .NET 5!

Amitpnk/Onion-architecture-ASP.NET-Core: WhiteApp API solution template which is built on Onion Architecture with all essential feature using .NET 5! (github.com)

WhiteApp or QuickApp API solution template which is built on Onion Architecture with all essential feature using .NET Core

Onion Architecture - Visual Studio Marketplace

WhiteApp Onion architecture with ASP.NET Core API

This is default white application for ASP.NET Core API development

This whiteapp contains following features, uncheck feature need to implement yet.

  • [x] Application is implemented on Onion architecture
  • [x] .Net 5.0
  • [x] Web API
  • [x] Entityframework Core
  • [x] Expection handling
  • [x] Automapper
  • [x] Unit testing via NUnit
  • [x] Integration testing via NUnit
  • [x] Versioning
  • [x] Swagger UI
  • [x] CQRS Pattern

Below features will be implemented in infrastructure layer. You can plug and play based on your project.

  • [x] Loggings - seriLog
  • [x] Email
  • [x] Health checks UI
  • [x] JWT authentication with Microsoft Identity
  • [x] Role based Authorization
  • [x] Fluent validations
  • [x] Database Seeding
  • [x] Enable CORS origin
  • [x] Enable feature flag (Make it true when you configure your email configuration)

image

Use this template

gtechsltn/Onion-Architecture-ASP-NET-Core (github.com)

gtechsltn/SimpleWebApps (github.com)

6) Clean Architecture Template for .NET 6.0 WebApi built with Multitenancy Support

fullstackhero/dotnet-webapi-boilerplate: Clean Architecture Template for .NET 6.0 WebApi built with Multitenancy Support. (github.com)

Features

  •  Built on .NET 6.0
  •  Follows Clean Architecture Principles
  •  Completely Documented at fullstackhero.net
  •  Multi Tenancy Support
  •  Supports MySQL, MSSQL & PostgreSQL!
  •  Uses Entity Framework Core as DB Abstraction
  •  Flexible Repository Pattern
  •  Dapper Integration for Optimal Performance
  •  Serilog Integration
  •  Swagger Support
  •  Mapster
  •  API Versioning
  •  Response Caching - Distributed Caching
  •  Fluent Validations
  •  Audit Logging
  •  Advanced User & Role Based Permission Management
  •  Code Analysis & StyleCop Integration with Rulesets
  •  JSON Based Localization with Caching
  •  Hangfire Support
  •  File Storage Service
  •  Test Projects
  •  & Much More

Phần 2: Responsive Web Design

4 Tips for Using Responsive Web Design Effectively   - The Media Temple Blog

Phần 3: 50 tips for improving your software development game

Expert advice: 50 tips for improving your software development skills (techbeacon.com)

How do you keep improving as a software engineer? Some pieces of advice are valid no matter your experience level, but often the advice will depend on where you are in your career.

If you're a beginner, the best advice is to simply learn your language, frameworks, and tools top to bottom and gain more experience with a variety of different projects.

If you're an experienced software developer, you should constantly try to find new ways to optimize your code for readability, performance, and maintainability, and then practice making well-reasoned decisions about where to focus time and resources in your code—whether it's testing, performance optimization, or other technical debt.

Those are some of the themes you’ll find if you ask veteran software engineers to share their best advice for being a great programmer. There aren’t any well-kept secrets. The advice of many of the most successful developers is readily available to you on blogs and forums.

 

I’ve taken the most illustrative advice and recurring tips from blogs and forums and organized them into five categories that emerged as I compiled them. I've paraphrased and merged various similar tips into single snippets, and I've also left a few pieces of advice as untouched quotes from their authors.

Whether you have five, ten, or twenty years of experience programming—or if you have almost no experience—I think just about every developer will find some good ideas for self-improvement.

Domains, architecture, and design

1. The best programmers can take a complex problem, break it down into smaller pieces, solve each of those pieces, and then put everything back together to solve the initial problem.

2.  Software is just a tool for solving domain problems. Since it’s needed in almost all domains, develop in one that interests you. If you understand a domain well and are passionate about it, you’ll be a much better, more motivated developer. You’ll also be exponentially more valuable and lucrative to companies hiring in your chosen domain.

3.  Don’t let one domain pigeonhole you into one way of coding. An example would be a mobile developer who is mainly good at hooking together existing APIs but can't come up with a sane data representation. Don’t be a one-trick pony.

4.  Plan your code away from the computer. It will help you build a clear mental model before you start. You use the same strategy in writing, because if you don’t have an outline, your content becomes a messy stream of consciousness.

5.  “When you're stuck, write your program on paper. I'm serious. It's magic. This is standard practice in programming competitions. (I think it works because when you don't have to think about syntax you have more excess brain power to solve the actual problem.)” (Source)
Joseph Gentle

6.  “Compelling web apps tend to be the ones that use data in unexpected ways or in ways that solve everyday problems. Learn everything you can about data storage.” (Source)
Maggie Nelson

7.  As an architect, you can’t have blind spots in your understanding of your applications and their execution environments. You need to know how things work in the front end (UI), the back end, the data store, the OS, any virtualization layers, the hardware, the network, and the data center.

Languages, tools, and advancing from beginner to intermediate

8.  Contribute to open-source projects as a bridge from beginner to intermediate. Collaborate with the developers of the project and attend meetups to collaborate with other developers in person.

9.  Don’t let anything get in the way of that initial motivation to learn programming and just build something. Sometimes you block yourself by having too much focus on reading books or resources first. Other times beginners will try to find the perfect first language. Your first language doesn’t matter. What matters is learning to program well. Just start coding.

10.  "Learning programming languages is NOT learning how to program. Focus on programming techniques, problem solving, and analytical skills, not on learning as many languages as you can."
Richard Eng

11.  Learn multiple programming paradigms such as object-oriented programming, functional programming, reflective programming, etc. Believe it or not, your programming in one paradigm will improve after studying an alternative paradigm.

12.  "Wherever possible, always choose the simpler programming language. More complex languages increase the cognitive load on your brain. Simpler languages do not necessarily give up anything in terms of power or expressiveness."
Richard Eng

13.  Beginners learn just enough of their tools to get by. To become an intermediate or expert developer, you need to know your tools cold. Learn all of the features, menus, and context menus. Learn to use them without a mouse by memorizing keyboard shortcuts. Find every “tips and tricks” article available.

14.  Learn your stack on the deepest levels before you decide to reinvent the wheel. Peter Nixey gives a few good examples: “If you are a Ruby developer take time to learn the language's incredible range of methods. If you are a Node developer, take time to understand the architecture, the methods, and the mindset of Node. If you are an Angular developer go right up to the rock-face and understand the logic behind of the incredible architecture the core team is forging there right now. Ask before you invent.” (Source)
Peter Nixey

15.  The same goes for the languages you work in. Learn the most important libraries for your use cases. The more libraries you’re aware of, the less likely you are to try reinventing the wheel.

16.  Whenever you can, use programming languages that will eliminate entire classes of run-time errors. To do that, look for languages with features like strong typing, static typing, managed memory, and/or immutable data.

17.  “Frameworks, libraries, languages, never mind if you can’t understand what you find under the hood on your first attempt. You can always put them aside and return to them later, just see to it that you can take them apart and have a look. All the rules you have to follow when you first learn were invented by someone, you can make them yours to reinvent with some persistence. Steer clear of tools that put barriers in the way of this activity, those make you depend on them in the wrong way.” (Source)
Jan Christian Meyer

18.  “[When reading high-quality code], it might be tempting to look for main() and start from there, but you're likely to spend a lot of time just reading set-up code and command-line parsing. I prefer to scan the filenames to look for some activity that interests me and then dig into those files. It's not crucial to understand the whole project or the ins and outs of the entire design, you'll wear yourself out doing this. Read the code. Look at the comments, see what the authors are doing, and how they went about it.” (Source)
Andrew Binstock

19.  Create some of your own tools. (But of course, if you're going to use it in production, make sure it's not another wheel reinvention.)

20.  Make common programs that have been made before. Not for a production project (see “reinventing the wheel”), but as a learning project. If other developers can make a calculator, text editor, paint, Tetris, or Pong, then so can you. Look at several examples of these apps written by more experienced developers and try to learn their tricks.

21.  Develop an aesthetic appreciation for code. Read the source code of famous open-source tools and frameworks such as Ruby on Rails or Jenkins, and get familiar with norvig.com. Over time, you need to train yourself to know what great code looks like and what bad code “smells” like.

Code readability and maintainability

22.  “Don't ask permission to refactor, test, document etc. It's all part of ‘programming’. Don't ask permission to do your job.” (Source)
Jerome Terry

23.  "Fix what isn’t broken. You should go to your last project and read through the code. Think about what each piece does. There's a loop here, some sorting there, a bit of number crunching, screen updates, HTML generation, database CRUD, that sort of thing. Now replace the hard-coded HTML with a templating system, get the database CRUD out of your business objects and re-write it to use proper parameterized queries instead of string concatenation, replace all the "writelns" and "MessageBoxes" in your error handlers with a logging framework, refactor code that's trying to borrow methods from other classes, use locale-aware string formatting, stop guessing how big an array should be and use a dynamic collection, delete orphaned code." (Source)
Chris Wenham

24.  Most developers have heard the saying, "Always write code as if the person who ends up maintaining it will be a violent psychopath who knows where you live." What that means realistically is that you should write readable code that could be easily comprehended a year later by someone who’s disinterested and in a hurry. If you’ve ever had to dig through indecipherable code, you know why this is so important. Have some empathy for the developers who will read your code.

25.  Name variables so that other developers can understand your code better. This is a skill you need to nurture.

26.  Using inheritance often reduces testability and reusability of your object-oriented code in the long run. Your first choice should be using composition and interfaces.

27.  Don’t use design patterns like a hammer looking for a nail. If you don’t have a clear reason you need it, don’t use it.

28.  Always favor shallow code hierarchies to deep-nested code (whether it’s inside or outside a function). Deep-nested code is harder to maintain, harder to reuse, and more likely to create bugs.

29.  Reusable code is helpful and important, but trying to write overgeneralized, super flexible code is often a waste of time. This kind of code is usually harder to maintain and causes bugs. It’s okay to hardcode some things if your code is doing one task.

30.  Master the art of debugging using "print statements." There are many scenarios where a sophisticated debugger is not available to you, but I've never found a platform nor environment where you couldn't output textual information to a screen or file.
Richard Eng

31.  Having great writing and communication skills directly translates into programming capability. Joel Spolsky can elaborate on why this is:
"The difference between a tolerable programmer and a great programmer is not how many programming languages they know, and it's not whether they prefer Python or Java. It's whether they can communicate their ideas. By persuading other people, they get leverage. By writing clear comments and technical specs, they let other programmers understand their code, which means other programmers can use and work with their code instead of rewriting it. Absent this, their code is worthless."

32.  Just like natural languages, you haven’t mastered programming until you see and think in code. A popular book, Structure and Interpretation of Computer Programs, by Abelson, Sussman, is one of the best resources to help you do this. Don’t worry that its examples are in Scheme; it's an optimal language for learning to think in code.

Technical debt, code coverage, and process

33.  Donald Knuth, is known for his maxims “When in doubt, use brute force” and “Premature optimization is the root of all evil.” When he says “use brute force,” he means that you shouldn’t let yourself get stuck trying to come up with a prematurely optimal algorithm. Just use the simplest, unsophisticated algorithm that will work and iterate from there. Using the simplest formula will also help you better understand how your software should work so that you can start forming a mental model with which to think of better, more efficient algorithms.

34.  Know when to take on technical debt and when to pay it off so it doesn’t compound. When exploring (and discarding) different features and pivoting frequently, borrow heavily on technical debt. When your position is stable and your direction is clearer, optimize your remaining features and clean up bugs to pay off that technical debt before moving on to the next stage.

35.  Within the context of your projects, learn what the right amount of testing is. Too little and your software becomes unreliable and everyone is afraid to deploy to production. Too much and you’ll end up wasting too much time and resources writing and maintaining them, while also making the development process slower.

36.  Estimating time is hard. This is why iterative development methods such as Scrum are so popular. Push yourself and your team to have increasingly shorter release cycles. Surprisingly, shipping code more frequently reduces risk instead of increasing it. It forces you to have better organizational practices and make a better product for the customer with faster feedback.

37.  Commit your code in small, working chunks and write a detailed commit messages that will help developers find and understand bugs that may have been introduced in that commit. Just summarize what you did and why you did it.

38.  Most developers don’t think about security in every unit of code they write. Many think that frameworks will handle that for them. Don’t be like most developers.

39.  You can spend an exponentially greater amount of time hunting down the last 1% of bugs in a project than you would for the first 90%. If you’re not working in a domain that requires your software to work perfectly 99.999% of the time, then you should spend less time debugging the edge cases and features people probably won’t use.

Soft skills and productivity

40. Have large chunks of time set aside for focused coding each day. The quantity of time spent coding is meaningless if it’s full of interruptions such as meetings, emails, and web browsing.

41.  Communicate clearly with your team about what you’re doing each day. Talking about your architectural approaches will help you think about those approaches in new ways. It has nothing to do with proving to people that you’re doing good work. More likely, your team will have some ideas you would have never thought of on your own, and you’ll solve problems a lot faster. Your team should also document solutions and share them on a wiki to save valuable time for everyone.

42.  Don’t be ashamed to admit when you don’t know something. As a developer, you’re often solving new problems, so you can’t be expected to know all the solutions immediately. Trying to hide your lack of knowledge only slows the learning process.

43.  Don’t be afraid to share your unfinished work with others frequently.

44.  "Emotionally detach from your code. Find the code that you're the most proud of and delete it, then rewrite it from scratch in a different way. Use a "design pattern" that confuses you or that you hate (e.g., the Singleton) and figure out how to make it work. If necessary, delete that after you've got it working and try again with a new pattern or language. Not only will you learn that there's More Than One Way To Do It, but you'll learn that your code is transitory. Code, by its nature, is not just inextricably glued to its language, platform, and the APIs it consumes, but written in the form of ephemeral static charges, orientations of magnetic particles, subject to the whims of the market, Moore's Law, and your employer. … Remember that emotional detachment from code is a virtue, but this doesn't mean emotional detachment from your work is, too. In fact, another way to become emotionally detached from code is to put your interest into the outcome instead." (Source)
Chris Wenham

45.  Googling is a crucial developer skill. Learning how to do something you haven’t done before and finding optimal solutions from the collective intelligence of the developer community is half the battle in programming.

46.  "Good programmers know what to write, but great ones know what to rewrite (and reuse)." (Source)
Eric S. Raymond

47.  Teach. Even if you’re a novice at programming, you’re knowledgeable about something. Teaching teaches the teacher. And if you can train other workers, your manager should realize that you’re exponentially more valuable.

48.  Don’t focus on becoming a “10x” programmer. Read these articles by Matt Asay and Scott Hanselman to see why.

49.  “You won’t—you cannot—become a better programmer through sheer force of programming alone. You can only complement and enhance your existing programming skills by branching out. Learn about your users. Learn about the industry. Learn about your business. The more things you are interested in, the better your work will be.” (Source)
Jeff Atwood

50.  Make mistakes, ask questions, get rapid feedback, get uncomfortable, compare it to what you know, keep going. More on that here.

Phần 4: How to easily structure your solution

NMillard/BasicSolutionStructure (github.com)

gtechsltn/BasicSolutionStructure (github.com)

Useful links

ASP.NET Core Microservices with MongoDB

September 1, 2021 18:50

ASP.NET Core Microservices with MongoDB (edit)

  • MongoDB
  • Kafka
  • Microservices
  • ASP.NET Core

MongoDB and Data Streaming: Implementing a MongoDB Kafka Consumer - DZone Big Data

Data Streaming with Apache Kafka & MongoDB - EMEA (slideshare.net)

MongoDB Connector for Apache Kafka 1.5 Available Now | MongoDB

aspnetrun/run-aspnetcore-microservices: Microservices on .Net platforms which used Asp.Net Web API, Docker, RabbitMQ, MassTransit, Grpc, Ocelot API Gateway, MongoDB, Redis, PostgreSQL, SqlServer, Dapper, Entity Framework Core, CQRS and Clean Architecture implementation. Also includes Cross-Cutting concerns like Implementing Centralized Distributed Logging with Elasticsearch, Kibana and SeriLog, use the HealthChecks with Watchdog, Implement Retry and Circuit Breaker patterns with Polly and so on.. See Microservices Architecture and Step by Step Implementation on .NET Course w/ discount-> (github.com)

Whats Including In This Repository

We have implemented below features over the run-aspnetcore-microservices repository.

Catalog microservice which includes;

  • ASP.NET Core Web API application
  • REST API principles, CRUD operations
  • MongoDB database connection and containerization
  • Repository Pattern Implementation
  • Swagger Open API implementation

Basket microservice which includes;

  • ASP.NET Web API application
  • REST API principles, CRUD operations
  • Redis database connection and containerization
  • Consume Discount Grpc Service for inter-service sync communication to calculate product final price
  • Publish BasketCheckout Queue with using MassTransit and RabbitMQ

Discount microservice which includes;

  • ASP.NET Grpc Server application
  • Build a Highly Performant inter-service gRPC Communication with Basket Microservice
  • Exposing Grpc Services with creating Protobuf messages
  • Using Dapper for micro-orm implementation to simplify data access and ensure high performance
  • PostgreSQL database connection and containerization

Microservices Communication

  • Sync inter-service gRPC Communication
  • Async Microservices Communication with RabbitMQ Message-Broker Service
  • Using RabbitMQ Publish/Subscribe Topic Exchange Model
  • Using MassTransit for abstraction over RabbitMQ Message-Broker system
  • Publishing BasketCheckout event queue from Basket microservices and Subscribing this event from Ordering microservices
  • Create RabbitMQ EventBus.Messages library and add references Microservices

Ordering Microservice

  • Implementing DDD, CQRS, and Clean Architecture with using Best Practices
  • Developing CQRS with using MediatR, FluentValidation and AutoMapper packages
  • Consuming RabbitMQ BasketCheckout event queue with using MassTransit-RabbitMQ Configuration
  • SqlServer database connection and containerization
  • Using Entity Framework Core ORM and auto migrate to SqlServer when application startup

API Gateway Ocelot Microservice

  • Implement API Gateways with Ocelot
  • Sample microservices/containers to reroute through the API Gateways
  • Run multiple different API Gateway/BFF container types
  • The Gateway aggregation pattern in Shopping.Aggregator

WebUI ShoppingApp Microservice

  • ASP.NET Core Web Application with Bootstrap 4 and Razor template
  • Call Ocelot APIs with HttpClientFactory and Polly

Microservices Cross-Cutting Implementations

  • Implementing Centralized Distributed Logging with Elastic Stack (ELK); Elasticsearch, Logstash, Kibana and SeriLog for Microservices
  • Use the HealthChecks feature in back-end ASP.NET microservices
  • Using Watchdog in separate service that can watch health and load across services, and report health about the microservices by querying with the HealthChecks

Microservices Resilience Implementations

  • Making Microservices more resilient Use IHttpClientFactory to implement resilient HTTP requests
  • Implement Retry and Circuit Breaker patterns with exponential backoff with IHttpClientFactory and Polly policies

Ancillary Containers

  • Use Portainer for Container lightweight management UI which allows you to easily manage your different Docker environments
  • pgAdmin PostgreSQL Tools feature rich Open Source administration and development platform for PostgreSQL

Docker Compose establishment with all microservices on docker;

  • Containerization of microservices
  • Containerization of databases
  • Override Environment variables

What you'll learn

  • ASPNET Core Web API Development of Microservices
  • REST API Principles, CRUD Operations
  • Mongo DB and Redis NoSQL Database Connection on Docker
  • Entity Framework Core with SQL Server Database Connection on Docker
  • N-Layer implementation with Repository Pattern
  • Swagger Open API implementation
  • Consume Discount Grpc Service for inter-service sync communication to calculate product final price
  • Publish BasketCheckout Queue with using MassTransit and RabbitMQ
  • Build a Highly Performant inter-service gRPC Communication with Basket Microservice
  • Using Dapper for micro-orm implementation to simplify data access and ensure high performance
  • PostgreSQL database connection and containerization
  • Async Microservices Communication with RabbitMQ Message-Broker Service
  • Using RabbitMQ Publish/Subscribe Topic Exchange Model
  • Using MassTransit for abstraction over RabbitMQ Message-Broker system
  • Implementing DDD, CQRS, and Clean Architecture with using Best Practices
  • Developing CQRS with using MediatR, FluentValidation and AutoMapper packages
  • Consuming RabbitMQ BasketCheckout event queue with using MassTransit-RabbitMQ Configuration
  • Using Entity Framework Core ORM and auto migrate to SqlServer when application startup
  • Ocelot API Gateway Development of Microservices
  • Call Ocelot APIs with HttpClientFactory
  • The Gateway aggregation pattern in Shopping Aggregator
  • ASPNET Core Web Application with Bootstrap 4 and Razor template
  • Docker Compose Containerization of All Microservices
  • Use Portainer for Container lightweight management UI which allows you to easily manage your different Docker environments
  • pgAdmin PostgreSQL Tools feature rich Open Source administration and development platform for PostgreSQL

ASP.NET Core and MongoDB

July 25, 2021 16:05

ASP.NET Core and MongoDB (edit)

Cloud: AWS

Configuring the AWS SDK for .NET with .NET Core - AWS SDK for .NET (version 3) (amazon.com)

NuGet Packages:

+ AWSSDK.S3 (Amazon Simple Storage Service (Amazon S3), provides developers and IT teams with secure, durable, highly-scalable object storage.)

+ AWSSDK.Extensions.NETCore.Setup (Extensions for the AWS SDK for .NET to integrate with .NET Core configuration and dependency injection frameworks.)

AWSSDK.DynamoDBv2 (Amazon DynamoDB is a fast and flexible NoSQL database service for all applications that need consistent, single-digit millisecond latency at any scale.)

AWSSDK.CognitoIdentity (Amazon Cognito is a service that makes it easy to save user data, such as app preferences or game state, in the AWS Cloud without writing any backend code or managing any infrastructure. With Amazon Cognito, you can focus on creating great app experiences instead of having to worry about building and managing a backend solution to handle identity management, network state, storage, and sync.)

Amazon Cognito: User Identity Management

Successful web or mobile applications can reach millions of users, and it is critical that such applications have a robust and scalable approach for user and identity management.

Applications can have specific requirements, such as using their own identity store, or leveraging an existing identity provider such as Facebook, Google, or Amazon. Some need to use a combination of their own identity store with existing identity providers. This is often coupled with requirements for a user interface that handles user registration, login, user verification, and forgotten passwords.

Amazon Cognito enables you to add user sign-up, sign-in, and access control to your web and mobile apps quickly and easily. Amazon Cognito scales to millions of users and supports sign-in with social identity providers, including Facebook, Google, and Amazon, and enterprise identity providers via SAML 2.0.

Amazon Cognito can also be used to control access to REST APIS through integration with the Amazon API Gateway service, and can reduce the work to authenticate web application users by integrating with
the Application Load Balancer.

Security features include multi-factor authentication, checks for compromised credentials, account takeover protection, and phone and email verification. Amazon Cognito also supports application specific identity stores, user profiles, and customized workflows and user migration through Lambda triggers.

+ ASP.NET Core Identity for Amazon Cognito

Introducing the ASP.NET Core Identity Provider Preview for Amazon Cognito | AWS Developer Tools Blog

aws/aws-aspnet-cognito-identity-provider: ASP.NET Core Identity Provider for Amazon Cognito (github.com)

DB: MongoDB

MongoDB - How to backup and restore a database | Jason Watmore's Blog

Client: React JS Boilerplate

cornflourblue/react-signup-verification-boilerplate: React Boilerplate - Email Sign Up with Verification, Authentication & Forgot Password (github.com)

Framework: Open Source ASP.NET Core 5.0 Web API

vb-software/netcore-webapi-starter: .NET Core Web API Starter Template (github.com)

Article:

Build a Basic CRUD App with ASP.NET Core 3.0 and MongoDB | Okta Developer

Tag:

ASP.NET Core 3.1 - Role Based Authorization Tutorial with Example API | Jason Watmore's Blog

Idea:

c# - Simple token based authentication/authorization in asp.net core for Mongodb datastore - Stack Overflow

Authentication/Authorization:

Node + Mongo - Boilerplate API with Email Sign Up, Verification, Authentication & Forgot Password | Jason Watmore's Blog

  • Email sign up and verification
  • JWT authentication with refresh tokens
  • Role based authorization with support for two roles (User & Admin)
  • Forgot password and reset password functionality
  • Account management (CRUD) routes with role based access control
  • Swagger api documentation route

Node.js + MongoDB API - JWT Authentication with Refresh Tokens | Jason Watmore's Blog

ASP.NET Core 3.1 API - JWT Authentication with Refresh Tokens | Jason Watmore's Blog

Deep Validation

September 9, 2020 12:19

1) Deep Validation in ASP.NET Core (edit)

1.1) jQuery Validation in ASP.NET MVC 5

https://www.pluralsight.com/paths/mvc5

Suggested load order is:

  1. jquery.js
  2. bootstrap.js
  3. jquery.validate.js
  4. jquery.validate.unobtrusive.js

1.2) ASP.NET Core MVC Client Data Validation

ASP.NET Core MVC case study solution for codeArbor and PluralSight Guides. Demonstrates client data validation using view models, data annotations, jQuery unobtrusive validation, and the Core MVC ModelState object.

  • ASP.NET Core MVC
  • C#
  • HTML
  • JavaScript

https://github.com/ajsaulsberry/BlipValidate

http://www.codearbor.com/library/building-robust-numeric-fields-for-html-forms-with-aspnet-core-mvc/

2) OAuth2

https://pskb-prod.herokuapp.com/microsoft-net/implementing-simple-oauth-server-with-katana-and-membershipreboot

3) OpenJS

https://openjsf.org/projects/

ASP.NET Core

June 16, 2020 11:11

ASP.NET Core (edit)

----------------------------------------------------------------------------------------------------
Tutorial: Get started with Razor Pages in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start?view=aspnetcore-3.1&tabs=visual-studio

Part 2, add a model to a Razor Pages app in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/model?view=aspnetcore-3.1&tabs=visual-studio

Part 3, scaffolded Razor Pages in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/page?view=aspnetcore-3.1&tabs=visual-studio

Part 4, with a database and ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/sql?view=aspnetcore-3.1&tabs=visual-studio

Part 5, update the generated pages in an ASP.NET Core app
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/da1?view=aspnetcore-3.1

Part 6, add search to ASP.NET Core Razor Pages
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/search?view=aspnetcore-3.1

Part 7, add a new field to a Razor Page in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/new-field?view=aspnetcore-3.1&tabs=visual-studio

Part 8, add validation to an ASP.NET Core Razor Page
https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/validation?view=aspnetcore-3.1&tabs=visual-studio

----------------------------------------------------------------------------------------------------
Razor Pages with Entity Framework Core in ASP.NET Core - Tutorial 1 of 8
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/intro?view=aspnetcore-3.1&tabs=visual-studio

Part 2, Razor Pages with EF Core in ASP.NET Core - CRUD
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/crud?view=aspnetcore-3.1

Part 3, Razor Pages with EF Core in ASP.NET Core - Sort, Filter, Paging
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-3.1

Part 4, Razor Pages with EF Core migrations in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/migrations?view=aspnetcore-3.1&tabs=visual-studio

Part 5, Razor Pages with EF Core in ASP.NET Core - Data Model
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/complex-data-model?view=aspnetcore-3.1&tabs=visual-studio

Part 6, Razor Pages with EF Core in ASP.NET Core - Read Related Data
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/read-related-data?view=aspnetcore-3.1&tabs=visual-studio

Part 7, Razor Pages with EF Core in ASP.NET Core - Update Related Data
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/update-related-data?view=aspnetcore-3.1

Part 8, Razor Pages with EF Core in ASP.NET Core - Concurrency
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/concurrency?view=aspnetcore-3.1&tabs=visual-studio

----------------------------------------------------------------------------------------------------
ASP.NET Core MVC with EF Core - tutorial series
https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/?view=aspnetcore-3.1

----------------------------------------------------------------------------------------------------
Host ASP.NET Core on Windows with IIS
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/?view=aspnetcore-3.1

----------------------------------------------------------------------------------------------------
ASP.NET Core Middleware
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1

----------------------------------------------------------------------------------------------------
ASP.NET Hosting
https://dotnet.microsoft.com/apps/aspnet/hosting

----------------------------------------------------------------------------------------------------
ASP.NET Hosting | Windows Hosting at Winhost
https://www.winhost.com/home.aspx

----------------------------------------------------------------------------------------------------
Handle errors in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-3.1

----------------------------------------------------------------------------------------------------
Troubleshoot and debug ASP.NET Core projects - Debug ASP.NET Core apps
https://docs.microsoft.com/en-us/aspnet/core/test/troubleshoot?view=aspnetcore-3.1

----------------------------------------------------------------------------------------------------
Microsoft Security Advisory - ASP.NET Core Vulnerability

 

ASP.NET Core Web API with Entity Framework Core

January 13, 2020 23:59

ASP.NET Core Web API with Entity Framework Core (edit)

CRUD Operation in ASP.NET Core Web API with Entity Framework Core

https://www.codeproject.com/Articles/1259484/CRUD-Operation-in-ASP-NET-Core-Web-API-with-Entity

https://github.com/mukeshkumartech/CRUD-AspNetCore-WebAPI

ASP.NET Core 2.1 - Implement Entity Framework Core In A Code First Approach

https://www.c-sharpcorner.com/article/entity-framework-core-a-code-first-approach/

ASP.NET Core Web API with EF Core DB-First Approach

https://code-maze.com/asp-net-core-web-api-with-ef-core-db-first-approach/

https://github.com/CodeMazeBlog/ef-db-first

How To Quickly Create A New Database Using EntityFramework Core On ASP.Net Core

CompatibilityVersion.Version_2_1

http://bekenty.com/entityframework-core-asp-net-core/

https://github.com/BekenJB/EmployeeManagerWithEFCore

Xóa bản ghi trùng lặp trong SQL Server Table

WITH student_cte AS (
    SELECT 
        First_Name, 
		Last_Name,
		Phone, 
        ROW_NUMBER() OVER(
            PARTITION BY 
                First_Name, 
                Last_Name, 
                Phone
            ORDER BY 
                First_Name, 
                Last_Name, 
                Phone
        ) rn
     FROM dbo.Students
)
select * from student_cte;
WITH student_cte AS (
    SELECT 
        First_Name, 
		Last_Name,
		Phone, 
        ROW_NUMBER() OVER(
            PARTITION BY 
                First_Name, 
                Last_Name, 
                Phone
            ORDER BY 
                First_Name, 
                Last_Name, 
                Phone
        ) rn
     FROM dbo.Students
)
DELETE FROM student_cte WHERE rn >1;

IIS + System.DirectoryServices + Use C# to manage IIS + IIS Manager

October 10, 2018 22:23

Use C# To Manage IIS - Using System.DirectoryServices namespace (edit)

https://stackoverflow.com/questions/24124644/to-get-the-hosted-web-sites-names-from-iis

Use C# to manage IIS

https://www.codeproject.com/Articles/99634/Use-C-to-manage-IIS

Programmatically Manage IIS

https://www.codeproject.com/Articles/31293/Programmatically-Manage-IIS

Windows XP IIS Manager v1.7

https://www.codeproject.com/Articles/9860/Windows-XP-IIS-Manager-v

Need to install the "IIS Metabase and IIS 6 configuration compatibility 

Read more: https://drive.google.com/file/d/19G0_FwXX-odXPnXTk6jVBWCipBODFZdV/

https://docs.oracle.com/cd/E98457_01/opera_5_6_core_help/installing_oeds_on_windows_7_workstation_web_server_IIS_asp_dot_net.htm

https://social.technet.microsoft.com/Forums/windows/en-US/11501684-3e3a-476c-afcd-3b449a4da3c9/iis-6-metabase-and-iis-6-configuration-compatibility-install?forum=w7itproinstall

https://www.activexperts.com/support/network-monitor/online/iis6metabase/

Creating Web API in ASP.NET Core 2.0

https://www.codeproject.com/Articles/1264219/Creating-Web-API-in-ASP-NET-Core-2-0

Configuring HTTPS in ASP.NET Core 2.1

August 27, 2018 13:27

Configuring HTTPS in ASP.NET Core 2.1 (edit)

https://asp.net-hacker.rocks/2018/07/05/aspnetcore-ssl.html

ASP.NET Core and Dependencies Injection

July 29, 2018 00:34

ASP.NET Core and Dependencies Injection (edit)

https://joonasw.net/view/aspnet-core-di-deep-dive

Code review checklist

December 27, 2017 10:09

Code Review Checklist (edit)

https://www.guru99.com/asp-net-web-api-interview-questions.html

https://www.fullstack.cafe/blog/asp-net-web-api-interview-questions

AdminLTE.Core (HAY HAY HAY)

https://www.udemy.com/course/complete-aspnet-core-21-course/

Implementing CQRS Pattern with Vue.js & ASP.NET Core MVC

https://www.codeproject.com/Articles/5262285/Implementing-CQRS-Pattern-with-Vue-js-ASP-NET-Core

https://www.c-sharpcorner.com/article/implementing-cqrs-pattern-with-vue-js-asp-net-core-mvc/

Implementing CQRS Pattern with Vue.js & ASP.NET Core MVC

https://codeload.github.com/ColorlibHQ/AdminLTE/zip/v2.4.18 (HAY HAY HAY)

https://github.com/moemura/AdminLTE.Core (HAY HAY HAY)

https://github.com/moemura/AdminLTE.Core/releases/tag/2.0.1

https://github.com/dotnet-express/AdminLTE-Starter-Kit/releases

https://github.com/dotnet-express/AdminLTE-Starter-Kit/releases/tag/v0.8.0

https://github.com/go2ismail/adminlte-aspnetcore2-version

https://github.com/shehryarkn/Dynamic-User-Defined-Dashboards-Asp-Net-Core

https://github.com/shehryarkn/Asp-net-Core-Project-with-Admin-Template-Setup

Code Review

Checklist: https://www.michaelagreiler.com/code-review-checklist/

Google: https://blog.fullstory.com/what-we-learned-from-google-code-reviews-arent-just-for-catching-bugs/

Microsoft: https://www.michaelagreiler.com/code-reviews-at-microsoft-how-to-code-review-at-a-large-software-company/

Code Guide

https://www.cybersecuritycourses.com/course/dev544-secure-coding-in-net-developing-defensible-applications/ (HAY HAY HAY)

https://niccs.us-cert.gov/training/search/sans-institute/secure-coding-net-developing-defensible-applications (HAY HAY HAY)

Code Quality & Secure

1. Readability a.k.a. ‘Understandability’ (Khả năng đọc hoặc Khả năng hiểu được)
2. Maintainability (Bảo trì)
3. Security (Bảo mật)
4. Speed and Performance (Tốc độ và hiệu suất)
5. Documentation (Tài liệu)
6. Reinventing the Wheel (Phát minh lại bánh xe)
7. Reliability (Độ tin cậy)
8. Scalability (Khả năng mở rộng)
9. Reusability (Tái sử dụng)
10. Patterns (Mẫu)
11. Test Coverage and Test Quality (Phạm vi kiểm tra và chất lượng kiểm tra)
12. Fit for Purpose (Phù hợp cho mục đích)

https://www.enosecurity.com/training-tutorials-courses/secure-coding-in-asp-net-training/ (Tranining)

Audience / Target Group:

  • .NET Application Developers
  • C# Programmers
  • ASP.NET Developers
  • Managers, Architects and Technologists involved in deploying .NET applications

Topics: 

  • General Web Application Security Concepts
  • .NET Framework Security Features
  • Input Validation & Encoding
  • Input Driven Attacks
  • Validation Best Practices
  • Output Encoding
  • Common Authentication Weaknesses
  • Authorization Best Practices
  • Controlling Application Access
  • Password Security
  • Session Hijacking & Trapping
  • Protecting User Sessions & Tokens
  • Canonicalization Problems
  • Parameter Manipulation
  • Encryption, Confidentiality & Data Protection
  • Cookie-Based Attacks
  • Protecting Application Variables
  • Error Handling & Logging
  • Attacking via Error Messages
  • Secure Logging & Error Handling
  • Server Configuration & Code Management
  • Common App Server Misconfigurations
  • Protecting Application Code
  • XML Web Services
  • Overview of WSDL, SOAP & AJAX Security
  • Web Service Attacks
  • AJAX Pitfalls
  • Web Service Best Practices
  • Application Threat Modeling
  • Application Context
  • Identifying Attacks, Vulnerabilities & Countermeasures
  • Threat Modeling Tools
  • Cache Control Issues
  • SSL Best Practices

https://forums.asp.net/t/1926690.aspx?Secure+Coding+best+practices+guideline

https://download.microsoft.com/documents/uk/msdn/security/The Developer Highway Code.pdf

http://www.evoketechnologies.com/blog/code-review-checklist-perform-effective-code-reviews/

https://nyu-cds.github.io/effective-code-reviews/01-intro/

https://nyu-cds.github.io/effective-code-reviews/02-best-practices/

https://nyu-cds.github.io/effective-code-reviews/03-checklist/

Security Code Review

https://www.owasp.org/images/2/2e/OWASP_Code_Review_Guide-V1_1.pdf

RESTful API Lifecycle Management

https://dzone.com/refcardz/restful-api-lifecycle-management

LINQ

https://msdn.microsoft.com/en-us/library/bb308959.aspx

Code Review Checklist & Guidelines for CSharp Developers

https://www.codeproject.com/Reference/593751/Code-Review-Checklist-and-Guidelines-for-Csharp-De

Code Review Guidelines

https://www.codeproject.com/Articles/524235/Codeplusreviewplusguidelines

Assign Severity to Review Finding

The severity to find issues with code should go as below. Reviewer must focus on issues with High severity first and then to Medium severity and then Low severity issues.

    1. Naming Conventions and Coding style = Low
    2. Control Structures and Logical issues = Medium or High
    3. Redundant Code = High
    4. Performance Issues = High
    5. Security Issues = High
    6. Scalability Issues = High
    7. Functional Issues =High
    8. Error Handling = High
    9. Reusability = Medium

https://weblogs.asp.net/tgraham/44763

Code Review Checklist

In my previous blog post, we discussed about “10 Simple Code Review Tips for Effective Code Reviews”. Now, let’s take this topic further and explore the code review checklist, which would help to perform effective code reviews to deliver best quality software. 

This code review checklist also helps the code reviewers and software developers (during self code review) to gain expertise in the code review process, as these points are easy to remember and follow during the code review process. 

Let’s first begin with the basic code review checklist and later move on to the detailed code review checklist. 

Basic Code Review Checklist

Let’s discuss about the basic code review checklist, which can be very handy if you are a beginner in code reviews and/or during initial code reviews.

Code Review Checklist for Basic Code Review

While reviewing the code, ask yourself the following basic questions:

  1. Am I able to understand the code easily?
  2. Is the code written following the coding standards/guidelines?
  3. Is the same code duplicated more than twice?
  4. Can I unit test / debug the code easily to find the root cause?
  5. Is this function or class too big? If yes, is the function or class having too many responsibilities?

If you feel that the answer is not satisfactory to any of the above questions, then you can suggest/recommend code changes.

Detailed Code Review Checklist

The following code review checklist gives an idea about the various aspects you need to consider while reviewing the code:

Code Review Checklist - Expert Code Reviewer

1. Code formatting

While going through the code, check the code formatting to improve readability and ensure that there are no blockers:

a) Use alignments (left margin), proper white space. Also ensure that code block starting point and ending point are easily identifiable.

b) Ensure that proper naming conventions (Pascal, CamelCase etc.) have been followed. 

c) Code should fit in the standard 14 inch laptop screen.  There shouldn’t be a need to scroll horizontally to view the code. In a 21 inch monitor, other windows (toolbox, properties etc.) can be opened while modifying code, so always write code keeping in view a 14 inch monitor.

d) Remove the commented code as this is always a blocker, while going through the code. Commented code can be obtained from Source Control (like SVN), if required.

2. Architecture

a) The code should follow the defined architecture.

  1. Separation of Concerns followed
    • Split into multiple layers and tiers as per requirements (Presentation, Business and Data layers).
    • Split into respective files (HTML, JavaScript and CSS).
  1. Code is in sync with existing code patterns/technologies.
  2. Design patterns: Use appropriate design pattern (if it helps), after completely understanding the problem and context.

3. Coding best practices

  1. No hard coding, use constants/configuration values.
  2. Group similar values under an enumeration (enum).
  3. Comments – Do not write comments for what you are doing, instead write comments on why you are doing. Specify about any hacks, workaround and temporary fixes. Additionally, mention pending tasks in your to-do comments, which can be tracked easily.
  4. Avoid multiple if/else blocks.
  5. Use framework features, wherever possible instead of writing custom code.

4. Non Functional requirements

a) Maintainability (Supportability) – The application should require the least amount of effort to support in near future. It should be easy to identify and fix a defect.

  1. Readability: Code should be self-explanatory. Get a feel of story reading, while going through the code. Use appropriate name for variables, functions and classes. If you are taking more time to understand the code, then either code needs refactoring or at least comments have to be written to make it clear.
  2. Testability: The code should be easy to test. Refactor into a separate function (if required). Use interfaces while talking to other layers, as interfaces can be mocked easily. Try to avoid static functions, singleton classes as these are not easily testable by mocks.
  3. Debuggability: Provide support to log the flow of control, parameter data and exception details to find the root cause easily. If you are using Log4Net like component then add support for database logging also, as querying the log table is easy.
  4. Configurability: Keep the configurable values in place (XML file, database table) so that no code changes are required, if the data is changed frequently.

b) Reusability

  1. DRY (Do not Repeat Yourself) principle: The same code should not be repeated more than twice.
  2. Consider reusable services, functions and components.
  3. Consider generic functions and classes.

c) Reliability – Exception handling and cleanup (dispose) resources.

d) Extensibility – Easy to add enhancements with minimal changes to the existing code. One component should be easily replaceable by a better component.

e) Security – Authentication, authorization, input data validation against security threats such as SQL injections and Cross Site Scripting (XSS), encrypting the sensitive data (passwords, credit card information etc.)

f) Performance

  1. Use a data type that best suits the needs such as StringBuilder, generic collection classes.
  2. Lazy loading, asynchronous and parallel processing.
  3. Caching and session/application data.

g) Scalability – Consider if it supports a large user base/data? Can this be deployed into web farms?

h) Usability – Put yourself in the shoes of a end-user and ascertain, if the user interface/API is easy to understand and use. If you are not convinced with the user interface design, then start discussing your ideas with the business analyst.

5. Object-Oriented Analysis and Design (OOAD) Principles

  1. Single Responsibility Principle (SRS): Do not place more than one responsibility into a single class or function, refactor into separate classes and functions.
  2. Open Closed Principle: While adding new functionality, existing code should not be modified. New functionality should be written in new classes and functions.
  3. Liskov substitutability principle: The child class should not change the behavior (meaning) of the parent class. The child class can be used as a substitute for a base class.
  4. Interface segregation: Do not create lengthy interfaces, instead split them into smaller interfaces based on the functionality. The interface should not contain any dependencies (parameters), which are not required for the expected functionality.
  5. Dependency Injection: Do not hardcode the dependencies, instead inject them.

In most cases the principles are interrelated, following one principle automatically satisfies other principles. For e.g: if the ‘Single Responsibility Principle’ is followed, then Reusability and Testability will automatically increase.

In a few cases, one requirement may contradict with other requirement. So need to trade-off based on the importance of the weight-age, e.g. Performance vs Security. Too many checks and logging at multiple layers (UI, Middle tier, Database) would decrease the performance of an application. But few applications, especially relating to finance and banking require multiple checks, audit logging etc. So it is ok to compromise a little on performance to provide enhanced security.

Tools for Code Reviews

  1. The first step while assessing the code quality of the entire project is through a static code analysis tool. Use the tools (based on technology) such as SonarQube, NDepend, FxCop, TFS code analysis rules. There is a myth that static code analysis tools are only for managers.
  2. Use plug-ins such as Resharper, which suggests the best practices in Visual studio.
  3. To track the code review comments use the tools like Crucible, Bitbucket and TFS code review process.

Conclusion

The above code review checklist is not exhaustive, but provides a direction to the code reviewer to conduct effective code reviews and deliver good quality code. Initially, it would take some time to review the code from various aspects. After a bit of practice, code reviewers can perform effective code reviews, without much effort and time. If you would like to become an expert code reviewer, this code review checklist serves as a great starting point. Happy Code Reviewing!

Asp.Net Core

June 29, 2017 18:48

Hosting and deployment overview for ASP.NET Core apps

https://docs.microsoft.com/en-us/aspnet/core/publishing/

Frequently Asked Questions

https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-faq

User State Migration Tool (USMT)

Categories

Recent posts