Files
pos-system/apps/web-client-base-net

WebClientBase - Blazor Web App .NET 10

Base frontend web application cho GoodGo Platform được xây dựng với Blazor WebAssembly Hosted.

Features / Tính năng

  • Blazor WebAssembly Hosted - Client chạy trong browser, Server host API
  • Shared Library Pattern - DTOs và Validation được chia sẻ giữa Client và Server
  • Data Annotations Validation - Viết 1 lần, dùng chung cả 2 đầu
  • [ApiController] Auto-Validation - Server tự động validate, không cần if (!ModelState.IsValid)
  • Dark/Light Mode - CSS variables với theme toggle
  • Glassmorphism UI - Modern design với backdrop blur và shadows

Tech Stack

Layer Technology
Client Blazor WebAssembly (.NET 10)
Server ASP.NET Core Web API (.NET 10)
Shared Class Library với Data Annotations
Styling CSS Variables, Dark Mode

Project Structure / Cấu trúc dự án

web-client-base-net/
├── WebClientBase.slnx              # Solution file
├── src/
│   ├── WebClientBase.Client/       # Blazor WebAssembly
│   │   ├── Layout/                 # MainLayout, NavMenu
│   │   ├── Pages/                  # Razor pages (Products, Auth)
│   │   └── wwwroot/css/            # Design System CSS
│   ├── WebClientBase.Server/       # ASP.NET Core Host
│   │   └── Controllers/            # API Controllers
│   └── WebClientBase.Shared/       # Shared Library
│       └── DTOs/                   # Data Transfer Objects
└── Dockerfile

Getting Started / Bắt đầu

# Navigate to project
cd apps/web-client-base-net

# Restore packages
dotnet restore

# Run Server (hosts both API and Blazor client)
dotnet run --project src/WebClientBase.Server

# Open browser
# https://localhost:5001 hoặc http://localhost:5000

Shared Validation Pattern / Mẫu Validation Chia Sẻ

1. Define DTO with Validation (một lần)

// WebClientBase.Shared/DTOs/ProductDto.cs
public class ProductDto
{
    [Required(ErrorMessage = "Tên là bắt buộc / Name is required")]
    [StringLength(100, MinimumLength = 3)]
    public string Name { get; set; } = string.Empty;

    [Range(0.01, 1_000_000)]
    public decimal Price { get; set; }
}

2. Server (Auto-validation với [ApiController])

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpPost]
    public IActionResult Create(ProductDto request)
    {
        // Không cần if (!ModelState.IsValid) - [ApiController] đã làm hộ
        return Ok(ApiResponse<ProductDto>.Ok(request));
    }
}

3. Client (DataAnnotationsValidator)

<EditForm Model="@product" OnValidSubmit="HandleSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    
    <InputText @bind-Value="product.Name" />
    <ValidationMessage For="() => product.Name" />
    
    <button type="submit">Submit</button>
</EditForm>

API Endpoints

Method Endpoint Description
GET /api/products Get all products
POST /api/products Create product
PUT /api/products Update product
POST /api/auth/register Register user
POST /api/auth/login Login
GET /api/auth/profile/{id} Get profile
GET /health Health check