Blazor 应用中的数据检索 returns 空数组
Data retrieval in Blazor app returns null-array
我目前正在努力创建我的第一个 Blazor 项目,它应该是一个小型 CRUD 应用程序。我尝试遵循一些教程,但大多数都是过时的发布前教程,并且有许多差异让我感到困惑。
我的问题是我还不了解一些基本概念(尤其是 'services')。当我启动应用程序时,出现以下错误:
System.NullReferenceException: 'Object reference not set to an
instance of an object.'
Temporary local of type 'UserManagement.Models.Users[]> was null.
错误发生在 Index.razor 中的“@foreach (var user in users)”行。我会理解没有检索到数据。但是,我的用户 table 中有数据。所以我真的不知道错误可能在这里。
我们目前拥有的是:
Index.razor
@page "/"
@using Models
@using Data
@inject UserService us
<form method="post">
<input asp-page="/Create" type="button" value="Neuen Benutzer erstellen" />
</form>
<form method="post">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>UserID</th>
<th>Name</th>
<th>Supervisor</th>
<th>Ersteller</th>
<th>Erstelldatum</th>
<th>Optionen</th>
</tr>
</thead>
<tbody>
@foreach (var user in users)
{
<tr>
<td>@user.PkId</td>
<td>@user.UserId</td>
<td>@user.FirstName @user.LastName</td>
<td>@user.Supervisor</td>
<td>@user.CreationUser</td>
<td>@user.CreationDate</td>
<td>
<a>Delete Account</a><br />
<a asp-page="/Edit"> Edit Account</a>
</td>
</tr>
}
</tbody>
</table>
</form>
@code {
Users[] users;
protected override async Task OnInitializedAsync()
{
users = await us.GetUsersAsync();
}
}
}
UserService.cs
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using UserManagement.Models;
namespace UserManagement.Data
{
public class UserService
{
private static UserManagementContext _context;
public UserService (UserManagementContext context)
{
_context = context;
}
public async Task<Users[]> GetUsersAsync()
{
Users[] u;
u = await _context.Users.ToArrayAsync();
return u;
}
}
}
型号:Users.cs
using System;
using System.Collections.Generic;
namespace UserManagement.Models
{
public partial class Users
{
public int PkId { get; set; }
public int FkJobtitle { get; set; }
public int FkCostcenter { get; set; }
public int? FkLocation { get; set; }
public int? FkDepartment { get; set; }
public int? FkWorkplace { get; set; }
public int? FkLanguage { get; set; }
public string UserId { get; set; }
public string Salutation { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PersonalId { get; set; }
public string Supervisor { get; set; }
public string Telephone { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime CreationDate { get; set; }
public string CreationUser { get; set; }
public DateTime? ModificationDate { get; set; }
public string ModificationUser { get; set; }
public virtual CostCenter FkCostcenterNavigation { get; set; }
public virtual Department FkDepartmentNavigation { get; set; }
public virtual Jobtitle FkJobtitleNavigation { get; set; }
public virtual Language FkLanguageNavigation { get; set; }
public virtual Location FkLocationNavigation { get; set; }
}
}
当然还有脚手架 DbContext(摘录):
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace UserManagement.Models
{
public partial class UserManagementContext : DbContext
{
public UserManagementContext()
{
}
public UserManagementContext(DbContextOptions<UserManagementContext> options)
: base(options)
{
}
public virtual DbSet<Approver> Approver { get; set; }
public virtual DbSet<Branche> Branche { get; set; }
public virtual DbSet<CostCenter> CostCenter { get; set; }
public virtual DbSet<DealerCompany> DealerCompany { get; set; }
public virtual DbSet<Department> Department { get; set; }
public virtual DbSet<Jobtitle> Jobtitle { get; set; }
public virtual DbSet<Language> Language { get; set; }
public virtual DbSet<Location> Location { get; set; }
public virtual DbSet<Request> Request { get; set; }
public virtual DbSet<RequestTypes> RequestTypes { get; set; }
public virtual DbSet<SystemRole> SystemRole { get; set; }
public virtual DbSet<SystemType> SystemType { get; set; }
public virtual DbSet<Systems> Systems { get; set; }
public virtual DbSet<Users> Users { get; set; }
public virtual DbSet<Workplace> Workplace { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
.....
在我的启动过程中,我必须使用 services.AddTransient 而不是 AddSingleton 来加载 UserService,因为后者会 运行 出现以下错误:
System.AggregateException: 'Some services are not able to be
constructed (Error while validating the service descriptor
'ServiceType: UserManagement.Data.UserService Lifetime: Singleton
ImplementationType: UserManagement.Data.UserService': Unable to
resolve service for type 'UserManagement.Models.UserManagementContext'
while attempting to activate 'UserManagement.Data.UserService'.)'
渲染组件时,它会尝试在执行 OnInitializedAsync()
之前创建视图。
它为您提供 null ref exc,因为它尝试呈现页面,并且对于每个调用数组迭代器的 NextItem() 但数组为空。
index.razor中的解决方案初始化ctor中的数组或将声明更改为:
Users[] users = new Users[x];
其中 x 是您要存储在列表中的元素数。
对于灵活的解决方案,我推荐使用 List 而不是数组。
List<User> users = new List<User>();
在调用 OnInitialized
之前已经构建了渲染树,foreach
将在 users
仍然是 null
的时间执行。您可以先分配 users
和空数组,或者 my 首选变体,使用 if
检查是否应该尝试呈现用户。模板项目(有天气预报的)也是这样做的。
@page "/"
@using Models
@using Data
@inject UserService us
<form method="post">
<input asp-page="/Create" type="button" value="Neuen Benutzer erstellen" />
</form>
@if (users == null)
{
<p><em>Loading...</em></p>
}
else
{
<form method="post">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>UserID</th>
<th>Name</th>
<th>Supervisor</th>
<th>Ersteller</th>
<th>Erstelldatum</th>
<th>Optionen</th>
</tr>
</thead>
<tbody>
@foreach (var user in users)
{
<tr>
<td>@user.PkId</td>
<td>@user.UserId</td>
<td>@user.FirstName @user.LastName</td>
<td>@user.Supervisor</td>
<td>@user.CreationUser</td>
<td>@user.CreationDate</td>
<td>
<a>Delete Account</a><br />
<a asp-page="/Edit"> Edit Account</a>
</td>
</tr>
}
</tbody>
</table>
</form>
}
@code
{
Users[] users;
protected override async Task OnInitializedAsync()
{
users = await us.GetUsersAsync();
}
}
问题出在下面的代码行中:
u = await _context.Users.ToArrayAsync();
当你在上面的代码中使用await时,GetUsersAsync
方法会被挂起,直到等待的任务完成,然后OnInitializedAsync
方法也会被挂起。所以当Users数组为null时一个组件被渲染
把上面的代码改成
u = _context.Users.ToArray();
我目前正在努力创建我的第一个 Blazor 项目,它应该是一个小型 CRUD 应用程序。我尝试遵循一些教程,但大多数都是过时的发布前教程,并且有许多差异让我感到困惑。
我的问题是我还不了解一些基本概念(尤其是 'services')。当我启动应用程序时,出现以下错误:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Temporary local of type 'UserManagement.Models.Users[]> was null.
错误发生在 Index.razor 中的“@foreach (var user in users)”行。我会理解没有检索到数据。但是,我的用户 table 中有数据。所以我真的不知道错误可能在这里。
我们目前拥有的是:
Index.razor
@page "/"
@using Models
@using Data
@inject UserService us
<form method="post">
<input asp-page="/Create" type="button" value="Neuen Benutzer erstellen" />
</form>
<form method="post">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>UserID</th>
<th>Name</th>
<th>Supervisor</th>
<th>Ersteller</th>
<th>Erstelldatum</th>
<th>Optionen</th>
</tr>
</thead>
<tbody>
@foreach (var user in users)
{
<tr>
<td>@user.PkId</td>
<td>@user.UserId</td>
<td>@user.FirstName @user.LastName</td>
<td>@user.Supervisor</td>
<td>@user.CreationUser</td>
<td>@user.CreationDate</td>
<td>
<a>Delete Account</a><br />
<a asp-page="/Edit"> Edit Account</a>
</td>
</tr>
}
</tbody>
</table>
</form>
@code {
Users[] users;
protected override async Task OnInitializedAsync()
{
users = await us.GetUsersAsync();
}
}
}
UserService.cs
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using UserManagement.Models;
namespace UserManagement.Data
{
public class UserService
{
private static UserManagementContext _context;
public UserService (UserManagementContext context)
{
_context = context;
}
public async Task<Users[]> GetUsersAsync()
{
Users[] u;
u = await _context.Users.ToArrayAsync();
return u;
}
}
}
型号:Users.cs
using System;
using System.Collections.Generic;
namespace UserManagement.Models
{
public partial class Users
{
public int PkId { get; set; }
public int FkJobtitle { get; set; }
public int FkCostcenter { get; set; }
public int? FkLocation { get; set; }
public int? FkDepartment { get; set; }
public int? FkWorkplace { get; set; }
public int? FkLanguage { get; set; }
public string UserId { get; set; }
public string Salutation { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PersonalId { get; set; }
public string Supervisor { get; set; }
public string Telephone { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime CreationDate { get; set; }
public string CreationUser { get; set; }
public DateTime? ModificationDate { get; set; }
public string ModificationUser { get; set; }
public virtual CostCenter FkCostcenterNavigation { get; set; }
public virtual Department FkDepartmentNavigation { get; set; }
public virtual Jobtitle FkJobtitleNavigation { get; set; }
public virtual Language FkLanguageNavigation { get; set; }
public virtual Location FkLocationNavigation { get; set; }
}
}
当然还有脚手架 DbContext(摘录):
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace UserManagement.Models
{
public partial class UserManagementContext : DbContext
{
public UserManagementContext()
{
}
public UserManagementContext(DbContextOptions<UserManagementContext> options)
: base(options)
{
}
public virtual DbSet<Approver> Approver { get; set; }
public virtual DbSet<Branche> Branche { get; set; }
public virtual DbSet<CostCenter> CostCenter { get; set; }
public virtual DbSet<DealerCompany> DealerCompany { get; set; }
public virtual DbSet<Department> Department { get; set; }
public virtual DbSet<Jobtitle> Jobtitle { get; set; }
public virtual DbSet<Language> Language { get; set; }
public virtual DbSet<Location> Location { get; set; }
public virtual DbSet<Request> Request { get; set; }
public virtual DbSet<RequestTypes> RequestTypes { get; set; }
public virtual DbSet<SystemRole> SystemRole { get; set; }
public virtual DbSet<SystemType> SystemType { get; set; }
public virtual DbSet<Systems> Systems { get; set; }
public virtual DbSet<Users> Users { get; set; }
public virtual DbSet<Workplace> Workplace { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
.....
在我的启动过程中,我必须使用 services.AddTransient 而不是 AddSingleton 来加载 UserService,因为后者会 运行 出现以下错误:
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: UserManagement.Data.UserService Lifetime: Singleton ImplementationType: UserManagement.Data.UserService': Unable to resolve service for type 'UserManagement.Models.UserManagementContext' while attempting to activate 'UserManagement.Data.UserService'.)'
渲染组件时,它会尝试在执行 OnInitializedAsync()
之前创建视图。
它为您提供 null ref exc,因为它尝试呈现页面,并且对于每个调用数组迭代器的 NextItem() 但数组为空。
index.razor中的解决方案初始化ctor中的数组或将声明更改为:
Users[] users = new Users[x];
其中 x 是您要存储在列表中的元素数。
对于灵活的解决方案,我推荐使用 List 而不是数组。
List<User> users = new List<User>();
在调用 OnInitialized
之前已经构建了渲染树,foreach
将在 users
仍然是 null
的时间执行。您可以先分配 users
和空数组,或者 my 首选变体,使用 if
检查是否应该尝试呈现用户。模板项目(有天气预报的)也是这样做的。
@page "/"
@using Models
@using Data
@inject UserService us
<form method="post">
<input asp-page="/Create" type="button" value="Neuen Benutzer erstellen" />
</form>
@if (users == null)
{
<p><em>Loading...</em></p>
}
else
{
<form method="post">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>UserID</th>
<th>Name</th>
<th>Supervisor</th>
<th>Ersteller</th>
<th>Erstelldatum</th>
<th>Optionen</th>
</tr>
</thead>
<tbody>
@foreach (var user in users)
{
<tr>
<td>@user.PkId</td>
<td>@user.UserId</td>
<td>@user.FirstName @user.LastName</td>
<td>@user.Supervisor</td>
<td>@user.CreationUser</td>
<td>@user.CreationDate</td>
<td>
<a>Delete Account</a><br />
<a asp-page="/Edit"> Edit Account</a>
</td>
</tr>
}
</tbody>
</table>
</form>
}
@code
{
Users[] users;
protected override async Task OnInitializedAsync()
{
users = await us.GetUsersAsync();
}
}
问题出在下面的代码行中:
u = await _context.Users.ToArrayAsync();
当你在上面的代码中使用await时,GetUsersAsync
方法会被挂起,直到等待的任务完成,然后OnInitializedAsync
方法也会被挂起。所以当Users数组为null时一个组件被渲染
把上面的代码改成
u = _context.Users.ToArray();