【问题标题】:Data retrieval in Blazor app returns null-arrayBlazor 应用程序中的数据检索返回空数组
【发布时间】:2020-02-06 21:00:05
【问题描述】:

我目前正在努力创建我的第一个 Blazor 项目,该项目应该是一个小型 CRUD 应用程序。我尝试遵循一些教程,但大多数都是过时的预发布教程,并且有很多差异让我感到困惑。

我的问题是我还不了解一些基本概念(尤其是“服务”)。当我启动应用程序时,我收到以下错误:

System.NullReferenceException: '对象引用未设置为 对象的实例。'

'UserManagement.Models.Users[]> 类型的临时本地为空。

错误发生在 Index.razor 中的“@foreach (var user in users)”行。我会理解没有检索到数据。但是,我的用户表中有数据。所以我真的不知道错误可能在这里。

到目前为止,我们拥有的是:

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: '有些服务不能 构造(验证服务描述符时出错 '服务类型:UserManagement.Data.UserService 生命周期:单例 实施类型:UserManagement.Data.UserService':无法 解析“UserManagement.Models.UserManagementContext”类型的服务 尝试激活“UserManagement.Data.UserService”时。)”

【问题讨论】:

  • u = (await _context.Users?.ToArrayAsync() ) ?? new Users[0]) 怎么样;
  • something设置为users,例如Users[] users=new Users[0];。不要让它为空

标签: asp.net-core blazor blazor-server-side


【解决方案1】:

当一个组件被渲染时,它会在OnInitializedAsync() 被执行之前尝试创建视图。 它为您提供 null ref exc,因为它尝试呈现页面并且 for each 调用数组迭代器的 NextItem() 但数组为 null。

index.razor 中的解决方法是在 ctor 中初始化数组或者将声明改为: Users[] users = new Users[x]; 其中 x 是要存储在列表中的元素数。 对于灵活的解决方案,我建议使用 List 而不是数组。 List&lt;User&gt; users = new List&lt;User&gt;();

【讨论】:

    【解决方案2】:

    问题出在以下代码行:

     u = await _context.Users.ToArrayAsync();
    

    当你在上面的代码中使用await时,方法GetUsersAsync被挂起,直到等待的任务完成,然后方法OnInitializedAsync也将被挂起。所以当组件被渲染时Users数组为空

    把上面的代码改成

     u = _context.Users.ToArray();
    

    【讨论】:

      【解决方案3】:

      在调用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();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 2017-04-03
        • 1970-01-01
        • 2022-07-18
        • 1970-01-01
        • 2019-02-16
        • 1970-01-01
        相关资源
        最近更新 更多