当我try 将依赖项注入与非参数构造函数一起使用时,我在Blazor服务器应用程序中遇到了‘MissingMethodException’MissingMethodException: Cannot dynamically create an instance of type 'Blazor.Pages.Account.Register'. Reason: No parameterless constructor defined.以下是我到目前为止try 过的:

我已经创建了UserService.cs

using Blazor.API.Model;

namespace Blazor.Services
{
    public class UserService
    {
        private readonly HttpClient _httpClient;
        public UserService(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }

        public async Task<bool> RegisterAsync(RegisterModel registerModel)
        {
            try
            {
                var response = await _httpClient.PostAsJsonAsync("/register", registerModel);
                if (response.IsSuccessStatusCode)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }
    }
}

我已经更新了Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();


builder.Services.AddScoped<HttpClient>(s =>
{
    var httpClient = new HttpClient
    {
        BaseAddress = new Uri(builder.Configuration.GetSection("ApiBaseUrl").Value)
    };
    return httpClient;
});
builder.Services.AddHttpClient();
builder.Services.AddScoped<UserService>();
var app = builder.Build();

另外,当我将鼠标悬停在builder.Configuration.GetSection("ApiBaseUrl").Value时,我收到错误"Warning CS8604 Possible null reference argument for parameter 'uriString' in 'Uri.Uri(string uriString)'"

和我的注册表.razor.cs

using Blazor.API.Model;
using Blazor.Services;

namespace Blazor.Pages.Account
{
    public partial class Register
    {
        private UserService UserService { get; set; }
        private bool isRegistering = false;
        private bool registrationSuccessful = false;
        private RegisterModel registerModel = new RegisterModel();
        
        public Register(UserService userService)
        {
            UserService = userService;
        }
        

        private async Task HandleValidSubmit()
        {
            // Start the registration process
            isRegistering = true;

            //send the registration request to the server
            bool registrationResult = await UserService.RegisterAsync(registerModel); 

            // Update the registration state
            registrationSuccessful = registrationResult;

            // Stop the registration process
            isRegistering = false;
        }
    }
}

但是,当我导航到此RegisterComponent时,我收到了‘MissingMethodException’错误.我也try 过添加无参数构造函数,但它导致了一个警告:‘不可为空的属性必须包含非空值’.

我如何解决这个问题,并正确使用依赖注入与Blazor组件的非参数构造函数?

这是我的登记簿.剃须刀

@page "/register"

<h3 class="text-center">Register</h3>
<div class="form-container">
<EditForm Model="@registerModel" OnValidSubmit="HandleValidSubmit" >
    <DataAnnotationsValidator />
    <ValidationSummary />

    <div class="form-group">
        <label for="FirstName" class="form-label">First Name</label>
        <InputText id="FirstName" @bind-Value="registerModel.FirstName" class="form-control" />
        <ValidationMessage For="@(() => registerModel.FirstName)" />
    </div>

    <div class="form-group">
        <label for="LastName" class="form-label">Last Name</label>
        <InputText id="LastName" @bind-Value="registerModel.LastName" class="form-control" />
        <ValidationMessage For="@(() => registerModel.LastName)" />
    </div>

    <div class="form-group">
        <label for="Email" class="form-label">Email</label>
        <InputText id="Email" @bind-Value="registerModel.Email" class="form-control" />
        <ValidationMessage For="@(() => registerModel.Email)" />
    </div>

    <div class="form-group">
        <label for="PhoneNumber" class="form-label">Phone Number</label>
        <InputText id="PhoneNumber" @bind-Value="registerModel.PhoneNumber" class="form-control" />
        <ValidationMessage For="@(() => registerModel.PhoneNumber)" />
    </div>

    <div class="form-group">
        <label for="Password" class="form-label">Password</label>
        <InputText id="Password" @bind-Value="registerModel.Password" class="form-control" type="password" />
        <ValidationMessage For="@(() => registerModel.Password)" />
    </div>

        <div class="text-center">
            <button type="submit" class="btn btn-primary" disabled="@isRegistering">
                @if (isRegistering)
                {
                    <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                    <text>Registering...</text>
                }
                else if (registrationSuccessful)
                {
                    <text>Registration Successful</text>
                }
                else
                {
                    <text>Register</text>
                }
            </button>
        </div>
        <p class="text-center mt-3">
        Already have an account? <a href="/login">Login here</a>
    </p>
</EditForm>
</div>

@code {
   
}

和我的appSetting.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ApiBaseUrl": "https://localhost:44330/"
}

我是Blazor服务器应用程序的初学者,目前我正在学习如何在Blazor服务器应用程序中连接和交互API.具体地说,我正在致力于实现用户注册和登录功能.然而,我在设置HttpClient和为注册过程建立正确的流程方面遇到了困难,如本文所述.

推荐答案

而@Sam的大部分答案都是正确的.我想补充几点.

之所以会出现该警告,是因为在您的appsettings.json或其他配置文件中可能找不到"ApiBaseUrl".现在由你来处理找不到它的情况,例如null.

这里有两种方法来处理它.

1. Handling null states

使用空值条件运算符(?.)和空合并运算符(??),我们可以为"ApiBaseUrl"为空值的情况声明"defaultUrl".就像这样:

BaseAddress = new Uri(builder.Configuration.GetSection("ApiBaseUrl")?.Value ?? "defaultUrl")

2. Surpressing warning with ! operator.

我们可以通过对可能的空对象使用!运算符来消除警告.这告诉编译器Value绝对不是空的. 如果它最终没有找到它,那么您将有一个运行时NullReferenceException异常.

BaseAddress = new Uri(builder.Configuration.GetSection("ApiBaseUrl").Value!)

一般来说,您不应该在Blazor .razor文件中真正使用构造函数.你应该使用这blazor component lifecycles种方法.这意味着如果你想对Blazor组件使用依赖注入,那么就应该使用属性注入.

以下是如何在以下情况下使用它:

  1. .razor分量,即register.razor.
@inject UserService UserService
  1. 文件后面有.razor.cs个代码,即register.razor.cs.
[Inject]
public UserService UserService { get; set; }

您可以在组件或代码隐藏文件中声明它.通常,如果您有一个代码,那么您应该在那里声明它.

这就是您应该如何使用属性注入更改您的register.razor.cs代码.

namespace Blazor.Pages.Account
{
    public partial class Register
    {
        [Inject]
        public UserService UserService { get; set; }
        
        private bool isRegistering = false;
        private bool registrationSuccessful = false;
        private RegisterModel registerModel = new RegisterModel();       

        private async Task HandleValidSubmit()
        {
            // Start the registration process
            isRegistering = true;

            //send the registration request to the server
            bool registrationResult = await UserService.RegisterAsync(registerModel); 

            // Update the registration state
            registrationSuccessful = registrationResult;

            // Stop the registration process
            isRegistering = false;
        }
    }
}

Csharp相关问答推荐

我无法在Program.cs中实例化我的学生类

从Key Vault中提取值以在本地dev web.connect中使用

使用特定格式的JsonConvert序列化对象

FileStream. FlushAsync()是否确保文件被写入磁盘?

MongoDB.NET-将数据绑定到模型类,但无法读取整数值

单行上的ReSharper数据标注

如何在Cosmos SDK中控制超时、重试和重试之间的延迟?

Lambda表达式如何与隐式强制转换一起工作?

在try 使用访问服务器上的文件夹时,如何解决CORS错误.NET核心API

为值对象编写自定义JsonConverter

有条件地定义预处理器指令常量

使用ASP.NET MVC for Lemon Squeezy X-Signature创建散列

实体框架-IsRequired()与OnDelete()

Blazor Server/.NET 8/在初始加载时调用异步代码是否冻结屏幕,直到第一次异步调用完成?

多个选项卡上的MudForm验证

C#中类库项目的源代码生成器

将J数组转换为列表,只保留一个嵌套的JToken

WPF:如何从DatagridHeader的内容模板绑定到词典项

无法使用直接URL通过PictureBox.ImageLocation加载图像

使用SQL Server 2022+时,我是否必须将代码从SqlConnection类对象中迁移出来?