如何在 .NET 8 中的 Blazor UI for Identity 中实现扩展用户属性?

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

我在将数据保存到 Blazor UI for Identity .NET 8 中的扩展用户属性时遇到问题。

我的问题是,在

OnValidSubmitAsync()
中的
Components/Account/Pages/Manage/Index.razor
方法中,只保存了电话号码,但没有保存其他内容。

我已将问题范围缩小到

OnValidSubmitAsync()
内的这些行无法获取表单字段数据:

user.Introduction = Input.Introduction;
user.Website = Input.Website;
user.Instagram = Input.Instagram;
user.TwitterX = Input.TwitterX;
user.Facebook = Input.Facebook;

如果我尝试硬编码一个值,它就会成功保存:

user.Website = "www.test.com";

所以我猜这是一个数据绑定问题。

我已将

ApplicationUser
重命名为
User
,它继承自
IdentityUser
:

public class User : IdentityUser
{
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
    public bool HasProfileImage { get; set; }
    public bool HasBackgropImage { get; set; }
    public string Introduction { get; set; } = string.Empty;
    public string? Website { get; set; }
    public string? Instagram { get; set; }
    public string? TwitterX { get; set; }
    public string? Facebook { get; set; }
    public List<Recipe> Recipes { get; set; } = [];
}

我的

DataContext
配置正确,并且模型中的所有属性都作为数据库中
AspNetUser
表中的列找到。

Program.cs

builder.Services.AddIdentityCore<User>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<DataContext>()
    .AddSignInManager()
    .AddDefaultTokenProviders();

我已在 SQL Server Management Studio 中手动输入测试数据,所有扩展字段都已成功加载到

OnInitializedAsync()
中并在表单字段中正确显示。

这是我的全部

Index.razor
:

@page "/Account/Manage"

@inject UserManager<User> UserManager
@inject SignInManager<User> SignInManager
@inject IdentityUserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager

<PageTitle>Profile</PageTitle>

<h3>Profile</h3>
<StatusMessage />

<div class="row">
    <div class="col-md-6">
        <EditForm Model="Input" FormName="profile" OnValidSubmit="OnValidSubmitAsync" method="post">
            <DataAnnotationsValidator />
            <ValidationSummary class="text-danger" role="alert" />
            <div class="form-floating mb-3">
                <input type="text" value="@username" class="form-control" disabled />
                <label for="username" class="form-label"><i class="bi bi-envelope-at"></i> Brukernavn</label>
            </div>
            <div class="form-floating mb-3">
                <InputText @bind-Value="Input.PhoneNumber" class="form-control" placeholder="Phone number" />
                <label for="phone-number" class="form-label"><i class="bi bi-phone"></i> Phone number</label>
                <ValidationMessage For="() => Input.PhoneNumber" class="text-danger" />
            </div>
            <div class="form-floating mb-3">
                <InputText @bind-Value="Input.Introduction" class="form-control" placeholder="Introduction" />
                <label for="introduction" class="form-label"><i class="bi bi-blockquote-left"></i> Introduction</label>
            </div>
            <div class="d-flex flex-row row row-cols-2">
                <div class="form-floating mb-3">
                    <InputText @bind-Value="Input.Website" class="form-control" placeholder="Website" />
                    <label for="website" class="form-label ms-3"><i class="bi bi-globe"></i> Website</label>
                </div>
                <div class="form-floating mb-3">
                    <InputText @bind-Value="Input.Instagram" class="form-control" placeholder="Instagram" />
                    <label for="instagram" class="form-label ms-3"><i class="bi bi-instagram"></i> Instagram</label>
                </div>
                <div class="form-floating mb-3">
                    <InputText @bind-Value="Input.TwitterX" class="form-control" placeholder="Twitter/X" />
                    <label for="twitterX" class="form-label ms-3"><i class="bi bi-twitter-x"></i> Twitter/X</label>
                </div>
                <div class="form-floating mb-3">
                    <InputText @bind-Value="Input.Facebook" class="form-control" placeholder="Facebook" />
                    <label for="facebook" class="form-label ms-3"><i class="bi bi-facebook"></i> Facebook</label>
                </div>
            </div>
            <button type="submit" class="w-100 btn btn-lg btn-success">
                <i class="bi bi-save"></i>
                Save
            </button>
        </EditForm>
    </div>
</div>

@code {
    private User user = default!;
    private string? username;
    private string? phoneNumber;
    private string? introduction;
    private string? website;
    private string? instagram;
    private string? twitterX;
    private string? facebook;

    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    [SupplyParameterFromForm(FormName = "profile")]
    private InputModel Input { get; set; } = new();

    protected override async Task OnInitializedAsync()
    {
        user = await UserAccessor.GetRequiredUserAsync(HttpContext);
        username = await UserManager.GetUserNameAsync(user);
        phoneNumber = await UserManager.GetPhoneNumberAsync(user);

        // These are all working. All the data is loaded from DB:
        Input.PhoneNumber ??= phoneNumber;
        Input.Introduction = user.Introduction;
        Input.Website = user.Website;
        Input.Instagram = user.Instagram;
        Input.TwitterX = user.TwitterX;
        Input.Facebook = user.Facebook;
    }

    private async Task OnValidSubmitAsync()
    {
        if (Input.PhoneNumber != phoneNumber)
        {
            var setPhoneResult = await UserManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
            if (!setPhoneResult.Succeeded)
            {
                RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not set phone number.", HttpContext);
            }
        }

        // The form field data is not being copied to the user-object here:
        user.Introduction = Input.Introduction;
        user.Website = Input.Website;
        user.Instagram = Input.Instagram;
        user.TwitterX = Input.TwitterX;
        user.Facebook = Input.Facebook;

        // Hard coded values are successfully saved:
        user.Website = "www.test.com";

        await UserManager.UpdateAsync(user); // This line is working

        await SignInManager.RefreshSignInAsync(user);
        RedirectManager.RedirectToCurrentPageWithStatus($"Your profile was updated.", HttpContext);
    }

    private sealed class InputModel
    {
        [Phone]
        [Display(Name = "Phone number")]
        public string? PhoneNumber { get; set; }

        // Exxtended fields
        public string? Introduction { get; set; }
        public string? Website { get; set; }
        public string? Instagram { get; set; }
        public string? TwitterX { get; set; }
        public string? Facebook { get; set; }
    }
}
c# data-binding blazor asp.net-core-identity .net-8.0
1个回答
0
投票

我认为你需要在绑定变量中使用

@
,否则它会将其作为字符串使用......

@bind-Value="Input.Facebook"
变成

@bind-Value="@Input.Facebook"

© www.soinside.com 2019 - 2024. All rights reserved.