Skip to content
This repository has been archived by the owner on May 12, 2022. It is now read-only.

ronnygunawan/express-netcore

Repository files navigation

NuGet

ExpressNetCore - Express-style wrapper for Asp.Net Core

Here's a fully working ASP.NET Core Web Application written in only a few lines of code using ExpressNetCore:

screenshot.png

Installation

Prerequisites:

Creating new project:

  • From Create a new project window select ASP.NET Core Web Application
  • Enter project name
  • Select ASP.NET Core 5.0 target framework, and Empty project type
  • In the newly created project, type following command in Package Manager Console:
Install-Package RG.ExpressNetCore

Hello World

var app = new ExpressApp();
app.MapGet("/", ctx => ctx.Response.WriteAsync("Hello world!!"));
app.Run();

Routing

app.MapDelete("/", ctx => ctx.Response.StatusCode = 204);
app.MapGet("/", ctx => ctx.Response.WriteAsync("Hello world!!"));
app.MapPost("/", (HttpContext ctx, Payload body) => ctx.Response.WriteAsync($"Hello {body.Name}!!"));
app.MapPut("/", ctx => ctx.Response.WriteAsync("Hello world!!"));
app.MapVerb("HEAD", "/", ctx => ctx.Response.WriteAsync("Hello world!!"));

Method-level Dependency Injection

Any specified lambda parameters will be resolved using Dependency Injection

app.AddTransient<IService, Service>();
app.MapGet("/students/{name}", (HttpResponse res, IService svc, string name) =>
    res.WriteJsonAsync(svc.GetStudent(name))
);
app.MapPost("/students", async (HttpResponse res, IService svc, AddStudentPayload body) => {
    await svc.AddStudentAsync(body.Name, body.Address);
    res.StatusCode = 201;
});

Available lambda parameters

1. Any registered services

// Register services
app.AddTransient<IStudentRepository, StudentRepository>();
app.AddTransient<ILogger, Logger>();

// Use registered services in lambda arguments. They will be automatically resolved.
app.MapPost("/students", async (HttpResponse res, IStudentRepository repo, ILogger logger, AddStudentPayload body) => {
    await repo.AddStudentAsync(body.Name, body.Address);
    logger.Log("Student added");
    res.StatusCode = 201;
});

2. Route parameters

// a and b will be resolved as route parameters with same name
app.MapGet("/add/{a}/{b}", (HttpResponse res, int a, int b) => res.WriteAsync($"{a + b}"));

3. Query strings

// a and b will be resolved as query strings with same name
// eg. /add?a=1&b=2
app.MapGet("/add", (HttpResponse res, int a, int b) => res.WriteAsync($"{a + b}"));

4. Request body (parameter must be named body)

app.MapPost("/add", (HttpResponse res, AddPayload body) => res.WriteAsync($"{body.A + body.B}"));

5. Request form (parameter must be of type IFormCollection)

app.MapPost("/add", (HttpResponse res, IFormCollection form) => res.WriteAsync($"You uploaded {form.Files.Count} files."));

6. HttpContext, HttpRequest, HttpResponse, and CancellationToken

Rendering Razor Views

app.MapGet("/students/{name}", (HttpResponse res, IService svc, string name) =>
    res.RenderAsync("Students/Profile", svc.GetStudent(name))
);

Routers

Works similar to MVC Controllers, but with method-level dependency injection

app.MapRouter<StudentsRouter>("/students");

public class StudentsRouter {
    private readonly IService _service;

    public StudentsRouter(IService service) {
        _service = service;
    }

    [MapGet("{name}")]
    public async Task GetStudent(HttpResponse res, string name) {
        res.RenderAsync("Students/Profile", _service.GetStudent(name));
    }
}

Hosting React SPA

Create a new folder containing your React app using npx create-react-app ClientApp, then configure your web app:

app.AddSpa(sourcePath: "ClientApp", buildPath: "ClientApp/build", devServerNpmScript: "start");

About

Express-style wrapper for Asp.Net Core

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published