Blazor从数据库绑定InputSelect下拉列表遇空引用异常问题
问题解决:Blazor InputSelect绑定动态数据时的空引用异常
问题根源
你代码里的context字段仅做了声明但未初始化,而StarRatings属性直接依赖这个未赋值的context,页面渲染时遍历StarRatings就会触发对象引用未设置为对象实例异常。另外还有一处ValidationMessage的绑定错误需要修正。
解决步骤
1. 初始化DbContext并异步加载下拉选项数据
在组件的生命周期方法OnInitializedAsync中,通过注入的DbFactory创建DbContext实例,并加载MovieStarRating数据(转为List而非直接用IQueryable,避免后续重复查询)。
2. 修正ValidationMessage的绑定目标
原来的ValidationMessage指向Movie.MovieStarRating,但你绑定的是Movie.MovieStarRatingId,需要修改匹配的表达式。
修改后的完整代码
@page "/movies/create" @rendermode InteractiveServer @using Microsoft.EntityFrameworkCore @using BlazorWebAppMovies.Models @using BlazorWebAppMovies.Data @inject IDbContextFactory<BlazorWebAppMovies.Data.BlazorWebAppMoviesContext> DbFactory @inject NavigationManager NavigationManager <PageTitle>Create</PageTitle> <h1>Create</h1> <h2>Movie</h2> <hr /> <div class="row"> <div class="col-md-4"> <EditForm method="post" Model="Movie" OnValidSubmit="AddMovie" FormName="create" Enhance> <DataAnnotationsValidator /> <ValidationSummary class="text-danger" role="alert"/> <div class="mb-3"> <label for="title" class="form-label">Title:</label> <InputText id="title" @bind-Value="Movie.Title" class="form-control" /> <ValidationMessage For="() => Movie.Title" class="text-danger" /> </div> <div class="mb-3"> <label for="releasedate" class="form-label">Release Date:</label> <InputDate id="releasedate" @bind-Value="Movie.ReleaseDate" class="form-control" /> <ValidationMessage For="() => Movie.ReleaseDate" class="text-danger" /> </div> <div class="mb-3"> <label for="genre" class="form-label">Genre:</label> <InputText id="genre" @bind-Value="Movie.Genre" class="form-control" /> <ValidationMessage For="() => Movie.Genre" class="text-danger" /> </div> <div class="mb-3"> <label for="price" class="form-label">Price:</label> <InputNumber id="price" @bind-Value="Movie.Price" class="form-control" /> <ValidationMessage For="() => Movie.Price" class="text-danger" /> </div> <div class="mb-3"> <label for="rating" class="form-label">Rating:</label> <InputText id="rating" @bind-Value="Movie.Rating" class="form-control" /> <ValidationMessage For="() => Movie.Rating" class="text-danger" /> </div> <div class="mb-3"> <label for="moviestarrating" class="form-label">Movie Star Rating:</label> <InputSelect id="moviestarrating" @bind-Value="Movie.MovieStarRatingId" class="form-control"> <option value="">-- Select --</option> @foreach (var movieStarRating in StarRatings) { <option value="@movieStarRating.Id">@movieStarRating.Descr</option> } </InputSelect> <ValidationMessage For="() => Movie.MovieStarRatingId" class="text-danger"></ValidationMessage> </div> <button type="submit" class="btn btn-primary">Create</button> </EditForm> </div> </div> <div> <a href="/movies">Back to List</a> </div> @code { private List<MovieStarRating> StarRatings = new(); [SupplyParameterFromForm] private Movie Movie { get; set; } = new(); protected override async Task OnInitializedAsync() { using var context = DbFactory.CreateDbContext(); StarRatings = await context.MovieStarRating.ToListAsync(); } private async Task AddMovie() { using var context = DbFactory.CreateDbContext(); context.Movie.Add(Movie); await context.SaveChangesAsync(); NavigationManager.NavigateTo("/movies"); } }
关键修改点说明
- 移除了未初始化的
context字段,改为在OnInitializedAsync中通过DbFactory创建临时context加载数据 - 将
StarRatings从IQueryable改为List<MovieStarRating>,避免页面渲染时重复触发数据库查询 - 修正了
ValidationMessage的绑定表达式,与InputSelect绑定的MovieStarRatingId保持一致
内容的提问来源于stack exchange,提问作者Rusty0918-B
相关产品推荐
相关产品推荐

