Skip to content

11. Web

There are several ways to do web development in .Net. The main framework for the web is ASP.NET Core. We will focus on Blazor.

mindmap
  root((ASP.NET Core))
    common
        cross platform
        runs in docker
        C#
        coops with Vue, ...
    Server
        API
            Routing
            middleware pipeline
        Server rendered
            Razor Pages
            MVC

    Blazor
        Render modes
            Server
            Static Server Side (SSR)
            Client: WebAssembly
            Hybrid
        Razor-syntax
        interactive
        binding
        Bootstrap

11.1 Blazor

  • Blazor Follow the instructions and build your first app: Build your first web app with ASP.NET Core using Blazor
    • Rider: Use the template Asp.Net Core Web Application
    • Visual Studio: Use the template Blazer Web App
    • CLI, https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-new-sdk-templates#blazor
      • dotnet new blazor --output demoblazor

11.1.1 Hosting Models

A component's hosting model is set by its render mode, either at compile time or runtime. We will work with the Blazor Server Render Mode.

Blazor Server

Comparison Table

Blazor WebAssembly

11.1.2 Component lifecycle

lifecycle
Blazor component lifecycle

11.1.3 Snippets

The Razor Syntax is easy, especially if you know Angular or React

@if (currentCount > 5){
    <h2>Great</h2>
}
You also have parameters similar to properties in Vue.
[Parameter]
public int IncrementAmount {get; set; } = 1;

<Counter IncrementAmount="2" />

Inline Code

@{
    int x = 7;
}
<p>x: @x</p>

Routes may have parameters with types.

@page "/counter/{InitialCount:int?}"

@code {
    [Parameter]
    public int? InitialCount {get; set; } = 0;
    protected override void OnInitialized()
    {
        currentCount = InitialCount ?? 0;
    }
}

Interaction

Any kind of interaction needs @rendermode InteractiveServer

<div class="mt-4">
    <input @onchange="OnChange" />
    <p>Hello @_name</p>
</div>

@code {
    string _name="";
    private void OnChange(ChangeEventArgs e) {
        _name = (string) e.Value!;
    }
}

We even have binding

<div class="mt-4">
    <input @onchange="OnChange" />
    <p>Hello @_name</p>
</div>
<p>Search</p>
<input @bind="_search" @bind:event="oninput" @bind:after="Search" />
<p>@_searchResult</p>
@code {
    string _name = "";
    string _search = "";
    string _searchResult = "";

    private void OnChange(ChangeEventArgs e)
    {
        _name = (string)e.Value!;
    }

    private async Task Search()
    {
        _searchResult = "searching...";
        await Task.Delay(2000);
        _searchResult = "found...";
    }

}

Take the time to explore the sample projects, run the provided examples, and read the linked articles for a deeper understanding

11.2 Web API

ASP.Net core offers similar possibilities to Node.js. To create your own REST service follow the instructions below.

dotnet new web -o AmazingDogs -f net8.0
dotnet add package Swashbuckle.AspNetCore

With the package Swashbuckle it is possible to generate an OpenApi Documenation automatically. Adapt program.cs as follows.

using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo {
        Title = "DogsApi API",
        Description = "Find an amazing dog",
        Version = "v1" });
});

var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "AmazingDogs API V1");
    });
}

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

app.Run();

Test your application.

OpenApi Documenation

To see the generated OpenApi Documenation add /swagger to the URL.

Follow the instructions of Add EF Core to minimal API and Use the SQLite database provider with EF Core to offer your DB as a REST service, which you may use for a Flutter application.

dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 8.0
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design --version 8.0

Create your DB-Context and your model class

public class Dog
{
    public string Name { get; set; }
    public string Breed { get; set; }
    public DateTime Birthday { get; set; }
    public int Id { get; set; }
} 

class DogDb : DbContext
{
    public DogDb(DbContextOptions options) : base(options) { }
    public DbSet<Dog> Dogs { get; set; } = null!;
}
Add the following lines to program.cs
var connectionString = builder.Configuration.GetConnectionString("Dogs") ?? "Data Source=Dogs.db";
builder.Services.AddSqlite<DogDb>(connectionString);

Define Migrations and Create the Database using

dotnet ef migrations add InitialCreate
dotnet ef database update
Check the output (it shows the sql to set up the database) and if the database (Defined in your DataSource) was created and explore it with any SQLite viewer.

Add CRUD operations as endpoints, e.g.

app.MapGet("/dogs", async (DogDb db) => await db.Dogs.ToListAsync());

app.MapPost("/dogs", async (DogDb db, Dog dog) =>
{
    await db.Dogs.AddAsync(dog);
    await db.SaveChangesAsync();
    return Results.Created($"/dog/{dog.Id}", dog);
});
Test your application using the generated OpenAPI. When you try the post method remove the id field to have an auto generated id, see figure below. post-example with openapi

You may deploy static sites or redirect http to https by using

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

For a complete example see Recipes from the book The MVVM Pattern in .NET MAUI.

11.3 Further Reading