我有一个 Blazor 组件,其中使用 InputSelect 来允许用户为用户选择角色。问题是 InputSelect 的 @bind-Value 没有按预期更新 SelectedRole 变量。当我尝试保存更改时,保存的角色是最初选择的角色,而不是在下拉列表中选择的角色。
这是我的代码的一部分:
<div class="row">
<div class="col-md-4">
<EditForm method="post" Model="User" OnValidSubmit="SaveChanges" FormName="EditUserForm">
<DataAnnotationsValidator />
<ValidationSummary role="alert" />
<div class="mb-3">
<label for="username" class="form-label">Nome</label>
<InputText id="username" @bind-Value="User.UserName" class="form-control" readonly />
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<InputText id="email" @bind-Value="User.Email" class="form-control" readonly />
</div>
<div class="mb-3">
<label for="role" class="form-label">Selecionar Role:</label>
<InputSelect id="role" @bind-Value="SelectedRole" class="form-group" >
<option value="-1">Nenhum</option>
@foreach (var role in AllRoles)
{
<option value="@role.Name">@role.Name</option>
}
</InputSelect>
</div>
<p>Selected Role: @SelectedRole</p>
<button type="submit" class="btn btn-primary"><img title="Gravar" src="/img/saveicon.png" style="height:30px" /></button>
<a href="/GereUsers" type="button" class="btn btn-outline-secondary"><img title="Recuar" src="/img/backicon.png" style="height:30px" /></a>
</EditForm>
</div>
</div>
}
<p class="text-info">@DebugMessage</p>
@code {
[SupplyParameterFromQuery]
private string? Id { get; set; }
private ApplicationUser? User;
private List<IdentityRole> AllRoles = new();
private string? SelectedRole;
private string DebugMessage { get; set; } = "Inicializando...";
protected override async Task OnInitializedAsync()
{
if (Id is not null)
{
User = await UserManager.FindByIdAsync(Id);
if (User is null)
{
DebugMessage = "Usuário não encontrado.";
NavigationManager.NavigateTo("/notfound");
return;
}
AllRoles = RoleManager.Roles.ToList();
var roles = await UserManager.GetRolesAsync(User);
SelectedRole = roles.FirstOrDefault() ?? "-1";
}
}
private async Task SaveChanges()
{
if (User is not null)
{
if (string.IsNullOrEmpty(SelectedRole) || SelectedRole == "-1")
{
var currentRoles = await UserManager.GetRolesAsync(User);
await UserManager.RemoveFromRolesAsync(User, currentRoles);
}
else
{
var currentRoles = await UserManager.GetRolesAsync(User);
var rolesToRemove = currentRoles.Where(r => r != SelectedRole).ToList();
await UserManager.RemoveFromRolesAsync(User, rolesToRemove);
if (!currentRoles.Contains(SelectedRole))
{
await UserManager.AddToRoleAsync(User, SelectedRole);
}
}
}
}
}
我尝试过的:
预期行为: 当从下拉列表中选择新角色时,SelectedRole 应更新,并且在提交更改时应保存正确的角色。
实际行为: SelectedRole 不反映新的选择,保存的角色仍保留为最初加载的角色。
如何确保 InputSelect 正确更新 SelectedRole 变量?
基于
我看不出您的代码有什么问题,但它可能出在您未显示的内容中。 这是基于您的代码的简化版本,作为单页演示。
@page "/"
<PageTitle>Home</PageTitle>
<div class="row">
<div class="col-md-4">
<EditForm method="post" Model="User" OnValidSubmit="SaveChanges" FormName="EditUserForm">
<div class="mb-3">
<label for="username" class="form-label">Nome</label>
<InputText id="username" @bind-Value="User.UserName" class="form-control" readonly />
</div>
<div class="mb-3">
<label for="role" class="form-label">Selecionar Role:</label>
<InputSelect id="role" @bind-Value="SelectedRole" class="form-group">
@if(SelectedRole is null)
{
<option disabled selected value="">-- Select A Role --</option>
}
@foreach (var role in AllRoles)
{
<option value="@role.Name">@role.Name</option>
}
</InputSelect>
</div>
<p>Selected Role: @SelectedRole</p>
<button type="submit" class="btn btn-primary"><img title="Gravar" src="/img/saveicon.png" style="height:30px" /></button>
<a href="/GereUsers" type="button" class="btn btn-outline-secondary"><img title="Recuar" src="/img/backicon.png" style="height:30px" /></a>
</EditForm>
</div>
</div>
}
<p class="text-info">@SelectedRole</p>
@code {
[SupplyParameterFromQuery]
private string? Id { get; set; }
private ApplicationUser User = new();
private List<IdentityRole> AllRoles = new();
private string? SelectedRole;
protected override async Task OnInitializedAsync()
{
await Task.Yield();
User = new ApplicationUser { UserName = "Tester" };
AllRoles = new List<IdentityRole>
{
new IdentityRole("Admin"),
new IdentityRole("User"),
new IdentityRole("Guest")
};
}
private async Task SaveChanges()
{
}
public class ApplicationUser
{
public string? UserName { get; set; }
}
public readonly record struct IdentityRole(string Name);
}