I am trying to build a simple app that iterates through 'Car' (model) names.
I am getting the following error when trying to iterate through items called through an API.
Index.cshtml:
@page
@model CarPageModel
<div class="text-center">
<h1 class="display-4">Cars</h1>
<hr/>
@foreach (var c in @Model.Cars) {
<span>@c.Name</span>
}
</div>
Index.cshtml.cs
Note: The API call works and returns data when entering debug mode.
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace CarApp.Pages;
public class CarPageModel : PageModel
{
private readonly ILogger<CarPageModel> _logger;
public CarPageModel(ILogger<CarPageModel> logger)
{
_logger = logger;
}
// Car is a Model
public List<Car> Cars { get; set; } = default!;
public async void OnGetAsync()
{
using(var httpClient = new HttpClient()) {
// Call controller api
var uri = new Uri("http://localhost:5009/api/cars");
using var response = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var stream = await response.Content.ReadAsStreamAsync();
var serializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var data = await JsonSerializer.DeserializeAsync<List<Car>>(stream, serializerOptions);
Cars = data == null ? [] : data;
}
}
}
Program.cs
using Microsoft.EntityFrameworkCore;
using CarApp;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
// Add appsettings.json
builder.Configuration.AddJsonFile("appsettings.json",
optional: true,
reloadOnChange: true);
var connectionString = builder.Configuration.GetConnectionString("AppDatabaseCS");
builder.Services.AddDbContext<CarContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddControllers();
builder.Services.AddHttpClient();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.MapControllers();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
I can provide additional code if needed. I just didn't think the controller / model class was relevant but I can provide if needed.
Note: I took a look at similar questions and they are saying to add 'return View()' but I don't know where to inject that code in my solution. But I don't know if that is relevant to my issue.
The error is telling you that Cars
is null
. And the code initializes it to null
:
public List<Car> Cars { get; set; } = default!;
Instead, initialize it to an empty list:
public List<Car> Cars { get; set; } = new List<Car>;
That way the loop will just silently iterate over 0 records.
Additionally, this is almost certainly wrong:
public async void OnGetAsync()
Using void
makes this method un-awaitable. So if the expectation is that the framework will be able to wait until Cars
is populated before continuing, this may prevent that. Return a Task
instead:
public async Task OnGetAsync()