Client Project
@page "/countrylist"
@inject ICountryService CountryService;
<PageTitle>Countries List</PageTitle>
<h3>Countries List</h3>
<table class="table">
<thead>
<tr>
<th>Country ID</th>
<th>Country Name</th>
</tr>
</thead>
<tbody>
@foreach (var country in CountryService.Countries)
{
<tr>
<td>@country.CountryId</td>
<td>@country.CountryName</td>
</tr>
}
</tbody>
</table>
@code {
protected override async Task OnInitializedAsync()
{
await CountryService.GetCountries();
}
}
Services > CountryService > CountryService.cs
using System.Net.Http.Json;
namespace BlazorCountriesWasm.Client.Services.CountryService
{
public class CountryService : ICountryService
{
private readonly HttpClient _http;
public CountryService(HttpClient http)
{
_http = http;
}
public List<Country> Countries { get; set; } = new List<Country>();
public HttpClient? Http { get; } //? here gets rid of green squiggly on "Public CountryService(HttpClient http)"
public async Task GetCountries()
{
var result = await _http.GetFromJsonAsync<List<Country>>("api/country");
if (result != null)
Countries = result;
}
public Task<Country> GetCountryById(int id)
{
throw new NotImplementedException();
}
}
}
Services > CountryService > ICountryService.cs
namespace BlazorCountriesWasm.Client.Services.CountryService
{
public interface ICountryService
{
List<Country> Countries { get; set; }
Task GetCountries();
Task<Country> GetCountryById(int id);
}
}
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">Countries & Cities</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="countrylist">
<span class="oi oi-list" aria-hidden="true"></span> Country List
</NavLink>
</div>
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
_Imports.razor
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorCountriesWasm.Client
@using BlazorCountriesWasm.Client.Shared
@using BlazorCountriesWasm.Client.Services.CountryService
Programs.cs
global using BlazorCountriesWasm.Client.Services.CountryService;
global using BlazorCountriesWasm.Shared;
using BlazorCountriesWasm.Client;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<ICountryService, CountryService>();
await builder.Build().RunAsync();
Server Project
Controllers > CityController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace BlazorCountriesWasm.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CityController : ControllerBase
{
public static List<City> cities = new List<City>
{
new City
{
CityId = 1,
CityName = "London",
CityPopulation = 9000000,
CountryId = 1
},
new City
{
CityId = 2,
CityName = "Birmingham",
CityPopulation = 1500000,
CountryId = 1
},
new City
{
CityId = 3,
CityName = "Oxford",
CityPopulation = 250000,
CountryId = 1
},
new City
{
CityId = 4,
CityName = "Cambridge",
CityPopulation = 200000,
CountryId = 1
},
new City
{
CityId = 5,
CityName = "Paris",
CityPopulation = 7500000,
CountryId = 2
},
new City
{
CityId = 6,
CityName = "Toulouse",
CityPopulation = 200000,
CountryId = 2
},
new City
{
CityId = 7,
CityName = "Grenoble",
CityPopulation = 200000,
CountryId = 2
}
};
[HttpGet]
public async Task<ActionResult<List<City>>> GetCities()
{
return Ok(cities);
}
[HttpGet]
[Route("{CityId}")]
//Or you can combine the two lines as: [HttpGet("{CityId}")]
public async Task<ActionResult<City>> GetSingleCity(int CityId)
{
var city = cities.FirstOrDefault(c => c.CityId == CityId);
if (city == null)
{
return NotFound();
}
else
{
return Ok(city);
}
}
}
}
Controllers > CountryController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace BlazorCountriesWasm.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CountryController : ControllerBase
{
public static List<Country> countries = new List<Country>
{
new Country {CountryId = 1, CountryName = "United Kingdom"},
new Country {CountryId = 2, CountryName ="France"}
};
[HttpGet]
public async Task<ActionResult<List<Country>>> GetCountries()
{
return Ok(countries);
}
[HttpGet]
[Route("{CountryId}")]
//Or you can combine the two lines as: [HttpGet("{CountryId}")]
public async Task<ActionResult<Country>> GetSingleCountry(int CountryId)
{
var country = countries.FirstOrDefault(c => c.CountryId == CountryId);
if (country == null)
{
return NotFound("Sorry, no country found.");
}
else
{
return Ok(country);
}
}
}
}
Shared Project
City.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlazorCountriesWasm.Shared
{
public class City
{
public int CityId { get; set; }
public string CityName { get; set; } = string.Empty;
public int CityPopulation { get; set; } = 0;
public int CountryId { get; set; }
}
}
Country.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlazorCountriesWasm.Shared
{
public class Country
{
public int CountryId { get; set; }
public string CountryName { get; set; } = String.Empty;
}
}