My .NET crash course
ASP.NET is a popular MVC framework for building web applications with C#. It's similar to Spring Boot if you come from a Java background and other web frameworks like Ruby on Rails and Laravel. Personally, I think it's more comparable to Spring Boot. We'll discuss this more later.
Follow the official documentation for installation.
File Structure
When I start learning a new framework, I usually relate its features to ones I'm familiar with. For example:
ApiController
- Define a REST Controller, like@RestController
in Spring BootDbContext
- Think of it like aJpaRepository
factory in Spring Boot, orActiveRecord
in RORProgram.cs
- The main class where the app initialisation is done, similar toSpringBootApplication
.csproj
- Where we define the configs, dependencies, like the mavenpom.xml
orbuild.gradle
in Java/Migrations
- A folder containing the db migration files, similar to the migrations in ROR.
C#
As a newcomer to C#, I found it surprisingly straightforward to learn. This is partly due to its similarities with other languages I'm familiar with, such as Java, JS, Kotlin, Ruby, and Dart. Here are a few examples:
- The
public, protected, private
keywords - The
var
andconst
variable assignment keywords - The getter and setter shorthands
get; set;
in Kotlin - The attribute
[...]
, which is equivalent to the annotation@
in Java - The
async
andawait
keywords
Development with VSCode
To run .NET directly from VSCode, you need to install these 2 extensions first.
Once these extensions are installed, please F5 to launch and debug.
CLI Commands
One thing I like about Ruby on Rails is its powerful CLI. It allows you to scaffold, generate classes, run migrations, and more. Fortunately, .NET also has its own CLI, and it’s actually pretty good.
Here are some commonly used commands in .NET:
-
dotnet new
- Create a new .NET projectdotnet new webapi --use-controllers -o dotnet-todo-api
-
dotnet add package
- Add a package dependencydotnet add package Microsoft.EntityFrameworkCore.InMemory
# If you are just starting, install these
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design 1 ↵ guster@Gusters-MacBook-Air
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet tool uninstall -g dotnet-aspnet-codegenerator
dotnet tool install -g dotnet-aspnet-codegenerator
dotnet tool update -g dotnet-aspnet-codegenerator
# for postgresql
Aspire.Npgsql.EntityFrameworkCore.PostgreSQL -
dotnet tool
- Install a CLI extension# install the Entity Framework CLI tool for database migration
dotnet tool install --global dotnet-ef -
dotnet ef migrations
- Generate a migration filedotnet ef migrations add InitialCreate
-
dotnet ef database update
- Apply the migrations to database -
dotnet aspnet-codegenerator
- Scaffolding such as controllerdotnet aspnet-codegenerator controller -name TodoItemsController -async -api -m TodoItem -dc TodoContext -outDir Controllers
-
dotnet run watch
- Run the project with hot reloading
How-to List
-
How to enable CORS?
If you are developing SPA with framework like React or Angular locally, you might hit CORS error when calling API to your local API server. To enable CORS, this is how you do it.
How to
In
Program.cs
, add the following codes.builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
var app = builder.Build();
// ...
app.UseCors(); -
Add a singleton
In
Program.cs
, add the following changes, assuming you have created a serviceAuthService
, then inject it in your class’s constructor as usual.builder.Services.AddSingleton<AuthService>()
-
Authorisation with JWT
Setup
To begin with, add the following service in your
Program.cs
builder.Services
.AddAuthorization()
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateActor = false,
ValidateIssuer = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
LogValidationExceptions = true,
ValidIssuer = "valid_issuer",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key"))
};
});
...
var app = builder.Build();
// IMPORTANT: the order matters!
app.UseAuthentication();
app.UseAuthorization();Helper class to generate a JWT token (AuthService)
public class AuthService
{
public string GenerateJwtToken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("your_secret_key");
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(
[
new Claim("id", user.Id.ToString())
]),
Issuer = "valid_issuer",
Expires = DateTime.UtcNow.AddHours(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}Protect your API endpoints
In your Controller, add this annotation
[Authorize]
to any endpoint method that required authorisation. Default is anonymous allowed.