System.NullReferenceException:“未将对象引用设置为对象的实例。” Blazor 服务器应用程序出现问题

问题描述 投票:0回答:1

我正在制作第一个 blazor 应用程序,当我尝试通过 Id 获取特定用户时遇到错误。

对于某些上下文,我使用 Blazor 服务器作为前端,并使用 .NET 8 API 作为后端

Blazor 页面代码:

@page "/User"
@page "/User/{Id:int}"
@rendermode InteractiveServer
@using System.Net.Http
@using Models
@using System.Text.Json;
@using System.Text
@using System.Security.Cryptography;
@inject HttpClient HttpClient
@inject NavigationManager NavManager


@if (Id == null)
{
    <h3>User Add</h3>
}
else
{
    <h3>User Edit</h3>
}

<form method="post" @onsubmit="AddUser" @formname="UserAdd" class="mt-4">
    <AntiforgeryToken />

    <div class="mb-3">
        <label for="name" class="form-label">Name:</label>
        <InputText type="text" @bind-Value="user!.Name" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="Company" class="form-label">Company:</label>
        <InputText type="text" @bind-Value="user!.Company" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="Department" class="form-label">Department:</label>
        <InputText type="text" @bind-Value="user!.Department" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="email" class="form-label">Email:</label>
        <InputText type="email" @bind-Value="user!.Email" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="Password" class="form-label">Password:</label>
        <InputText type="password" @bind-Value="user!.Password" class="form-control" required />
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
</form>


@code {
    [Parameter]
    public int? Id { get; set; }

    [SupplyParameterFromForm]
    public User? user { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (Id != null)
        {
            try{
                var response = await HttpClient.GetAsync($"https://localhost:7183/api/User/{Id}");
                response.EnsureSuccessStatusCode();

                var json = await response.Content.ReadAsStringAsync();
                user = JsonSerializer.Deserialize<User>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
            }
            catch (Exception ex)
            {
                // Handle error
                Console.WriteLine("Error getting user: " + ex.Message);
            }
        }
        else
        {
            user ??= new();
        }
    }

    void AddUser()
    {
        try
        {
            byte[] salt = GenerateSalt();
            user.Password = HashPassword(user.Password, salt);

            var client = new HttpClient();
            client.BaseAddress = new Uri("https://localhost:7183/api/User");

            var json = JsonSerializer.Serialize(user);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var response = client.PostAsync("User", content).Result;

            NavManager.NavigateTo("/UserOverview");
        }
        catch (Exception ex)
        {
            // Handle error
            Console.WriteLine("Error adding user: " + ex.Message);
        }
    }

    private string HashPassword(string password, byte[] salt)
    {
        using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000))
        {
            byte[] hash = pbkdf2.GetBytes(32); // 32 bytes for SHA256
            byte[] hashBytes = new byte[36]; // 32 bytes for hash + 4 bytes for salt

            Array.Copy(salt, 0, hashBytes, 0, 4);
            Array.Copy(hash, 0, hashBytes, 4, 32);

            return Convert.ToBase64String(hashBytes);
        }
    }

    private byte[] GenerateSalt()
    {
        byte[] salt = new byte[4]; // 4 bytes for salt
        using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
        {
            rngCsp.GetBytes(salt);
        }
        return salt;
    }
}

我有API方法:

group.MapGet("/{id}", async Task<Results<Ok<User>, NotFound>> (int id, DataContext db) =>
{
    return await db.User.AsNoTracking()
        .FirstOrDefaultAsync(model => model.Id == id)
        is User model
            ? TypedResults.Ok(model)
            : TypedResults.NotFound();
})
.WithName("GetUserById")
.WithOpenApi();

行后:

var response = await HttpClient.GetAsync($"https://localhost:7183/api/User/{Id}");

我收到此错误消息:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=CalibrationReportingToolFrontend
  StackTrace:
   at CalibrationReportingToolFrontend.Components.Pages.OtherPages.UserAdd.BuildRenderTree(RenderTreeBuilder __builder)

我想也许我正在寻找的ID在数据库中不存在,所以我尝试了这个:

var response = await HttpClient.GetAsync("https://localhost:7183/api/User/6");

除此之外,我还测试了我的 API 端点,这似乎按预期工作

c# .net api entity-framework blazor
1个回答
0
投票

当你这样做时,你告诉编译器“user”不为空:user!.Name。但是当剃刀页面很好地生成用户时可能为空。在引用“用户”之前检查一下。

@if(user is not null){
<form method="post" @onsubmit="AddUser" @formname="UserAdd" class="mt-4">
    <AntiforgeryToken />

    <div class="mb-3">
        <label for="name" class="form-label">Name:</label>
        <InputText type="text" @bind-Value="user!.Name" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="Company" class="form-label">Company:</label>
        <InputText type="text" @bind-Value="user!.Company" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="Department" class="form-label">Department:</label>
        <InputText type="text" @bind-Value="user!.Department" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="email" class="form-label">Email:</label>
        <InputText type="email" @bind-Value="user!.Email" class="form-control" required />
    </div>

    <div class="mb-3">
        <label for="Password" class="form-label">Password:</label>
        <InputText type="password" @bind-Value="user!.Password" class="form-control" required />
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
</form>
}
© www.soinside.com 2019 - 2024. All rights reserved.