Here’s a practical guide to pairing .NET with front-end options, including code examples to help you decide:
1. Traditional HTML/JavaScript + Lightweight Libraries
Example 1: HTMX + .NET API
- Goal: Fetch data from a .NET API and update the page without writing JavaScript.
- Backend (C#) Return HTML instead of JSON using Razor views:
// WeatherController.cs
[HttpGet("html")]
public IActionResult GetWeatherHtml()
{
var forecasts = new[] { "Sunny", "Cloudy", "Rainy" };
return PartialView("_WeatherPartial", forecasts);
}
Create a Razor partial view (_WeatherPartial.cshtml
):
@model string[]
class="weather-list">
@foreach (var forecast in Model)
{
@forecast
}
- Frontend (HTML with HTMX)
<span class="na">src="https://unpkg.com/htmx.org">
hx-get="/weather/html"
hx-target="#weather-container"
hx-indicator="#loading"
>
Load Weather
id="loading" class="hidden">Loading...
id="weather-container">
.hidden { display: none; }
[hx-indicator="#loading"]:not([hx-disabled-elt]) + #loading {
display: block;
}
Example 2: Alpine.js + Razor Pages
- Goal: Create a reactive counter without complex setup.
- Frontend (Razor Page):
x-data="{ count: 0 }">
@click="count++">+
x-text="count">
@click="count--">-
<span class="na">src="https://unpkg.com/alpinejs" defer>
2. Modern Frameworks (React/Vue/Angular)
Example 1: React + .NET Web API
- Goal: Build a dynamic list of items fetched from a .NET API.
- React Component:
// App.jsx
import { useEffect, useState } from 'react';
function App() {
const [items, setItems] = useState([]);
useEffect(() => {
fetch('/api/items') // Calls your .NET API
.then(res => res.json())
.then(data => setItems(data));
}, []);
return (
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
}
-
Setup: Use the
dotnet new react
template for a preconfigured React + .NET project.
Example 2: Vue + .NET
- Goal: Display a form that submits data to a .NET API.
- Vue Component:
<template>
@submit.prevent="submitForm">
v-model="name" placeholder="Enter name" />
type="submit">Save
template>
<script>
export default {
data() {
return { name: '' };
},
methods: {
submitForm() {
fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: this.name })
});
}
}
};
script>
3. Blazor (C# on the Front-End)
Example: Blazor Component
- Goal: Create an interactive list using C# instead of JavaScript.
- Component:
@page "/weather"
@inject HttpClient Http
Weather Forecast
@if (forecasts == null) {
Loading...
} else {
@foreach (var forecast in forecasts)
{
@forecast
}
}
@code {
private string[] forecasts;
protected override async Task OnInitializedAsync()
{
// Calls your .NET API directly
forecasts = await Http.GetFromJsonAsync("api/weather");
}
}
When to Use What?
Scenario | Recommended Approach |
---|---|
Simple CRUD app | HTML + HTMX/Alpine.js + Razor |
Team knows JavaScript well | React/Vue + .NET Web API |
Avoid JavaScript entirely | Blazor |
Legacy app maintenance | jQuery + MVC |
Key Takeaways:
- For quick results, stick to Razor Pages with Alpine.js or HTMX.
- For complex UIs (e.g., dashboards), use React/Vue with a .NET Web API.
- If you hate JavaScript, Blazor is your friend.