我在“Web 应用程序”中使用 .net 8 脚手架 blazor 身份页面并启用了自动功能。
我在表单中添加了一个硬编码值,并将 int Id 绑定到所选值。
但是,当提交表单时,该值始终为零。
ChatGPT 没有答案,从我在网上找到的内容来看,这应该可行。
为什么总是为零?
谢谢
@page "/Account/Register"
@using System.ComponentModel.DataAnnotations
@using System.Text
@using System.Text.Encodings.Web
@using Microsoft.AspNetCore.Identity
@using Microsoft.AspNetCore.WebUtilities
@using FootballHeadz3.Data
@inject UserManager<ApplicationUser> UserManager
@inject IUserStore<ApplicationUser> UserStore
@inject SignInManager<ApplicationUser> SignInManager
@inject IEmailSender<ApplicationUser> EmailSender
@inject ILogger<Register> Logger
@inject NavigationManager NavigationManager
@inject IdentityRedirectManager RedirectManager
@inject IUserRepository _userRepository
@* @rendermode InteractiveServer *@
<PageTitle>Register</PageTitle>
<h1>Register</h1>
@if (!String.IsNullOrEmpty(@Messagex))
{
<div class="alert alert-success" role="alert">
@Messagex
</div>
}
@if (!String.IsNullOrEmpty(@MessageErrorx))
{
<div class="alert alert-danger" role="alert">
@MessageErrorx
</div>
}
<div class="row">
<div class="col-md-8">
<StatusMessage Message="@Message" />
<EditForm Model="Input" asp-route-returnUrl="@ReturnUrl" method="post" OnValidSubmit="RegisterUser" FormName="register">
<DataAnnotationsValidator />
<ValidationSummary class="text-danger" role="alert" />
<div class="form-floating mb-3">
<InputText @bind-Value="Input.Email" class="form-control" autocomplete="username" aria-required="true" placeholder="[email protected]" />
<label for="email">Email</label>
<ValidationMessage For="() => Input.Email" class="text-danger" />
</div>
<div class="form-floating mb-3">
<InputText @bind-Value="Input.FHUsername" class="form-control" aria-required="true" placeholder="[email protected]" />
<label for="fhusername">Username (publicly visible, not email)</label>
<ValidationMessage For="() => Input.FHUsername" class="text-danger" />
</div>
<div class="form-floating mb-3">
<InputText maxlength="50" @bind-Value="Input.HowHearText" class="form-control" aria-required="true" placeholder="[email protected]" />
<label for="fhusername">How did you hear about us?</label>
<ValidationMessage For="() => Input.HowHearText" class="text-danger" />
</div>
@* this wont bind for some reason, just using a textbox *@
<div class="form-floating mb-3">
<select @bind="@Input.HowHearId" id="() => Input.HowHearId" class="form-select">
<option value="0">Please Select...</option>
<option value="1">Google</option>
<option value="2">YouTube</option>
<option value="3">Word of Mouth</option>
<option value="4">FPL Black Box</option>
<option value="100">Other</option>
</select>
<label for="howhearid">How did you hear about us?</label>
<ValidationMessage For="() => Input.HowHearId" class="text-danger" />
</div>
<div class="form-floating mb-3">
<InputText @bind-Value="Input.TeamSupported" class="form-control" aria-required="true" placeholder="[email protected]" />
<label for="teamsupported">Team Supported</label>
<ValidationMessage For="() => Input.TeamSupported" class="text-danger" />
</div>
<div class="form-floating mb-3">
<InputText @bind-Value="Input.Country" class="form-control" aria-required="true" placeholder="[email protected]" />
<label for="country">Country</label>
<ValidationMessage For="() => Input.Country" class="text-danger" />
</div>
<div class="form-floating mb-3">
<InputText @bind-Value="Input.XUsername" class="form-control" aria-required="true" placeholder="[email protected]" />
<label for="xusername">X/Twitter Username</label>
<ValidationMessage For="() => Input.XUsername" class="text-danger" />
</div>
<div class="form-floating mb-3">
<InputText type="password" @bind-Value="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
<label for="password">Password</label>
<ValidationMessage For="() => Input.Password" class="text-danger" />
</div>
@* <div class="form-floating mb-3">
<InputText type="password" @bind-Value="Input.HowHearId" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
<label for="confirm-password">How did you hear about us?</label>
<ValidationMessage For="() => Input.HowHearId" class="text-danger" />
</div> *@
<div class="form-floating mb-3">
<InputText type="password" @bind-Value="Input.ConfirmPassword" class="form-control" autocomplete="new-password" aria-required="true" placeholder="password" />
<label for="confirm-password">Confirm Password</label>
<ValidationMessage For="() => Input.ConfirmPassword" class="text-danger" />
</div>
<button type="submit" class="w-100 btn btn-lg btn-primary">Register</button>
</EditForm>
</div>
@* <div class="col-md-6 col-md-offset-2">
<section>
<h3>Use another service to register.</h3>
<hr />
<ExternalLoginPicker />
</section>
</div> *@
</div>
@code {
public string? Messagex { get; set; }
public string? MessageErrorx { get; set; }
private IEnumerable<IdentityError>? identityErrors;
[SupplyParameterFromForm]
//private InputModel Input { get; set; }
private InputModel Input { get; set; } = new();
public int _howHearId { get; set; }
[SupplyParameterFromQuery]
private string? ReturnUrl { get; set; }
private string? Message => identityErrors is null ? null : $"Error: {string.Join(", ", identityErrors.Select(error => error.Description))}";
public async Task RegisterUser(EditContext editContext)
{
if (await _userRepository.FHUsernameExistsAsync(Input.FHUsername))
{
MessageErrorx = "Username already exists, please choose another";
return;
}
var user = CreateUser();
// Map additional fields
user.TeamSupported = Input.TeamSupported;
user.Country = Input.Country;
user.FHUsername = Input.FHUsername;
user.XUsername = Input.XUsername;
user.HowHearText = Input.HowHearText;
user.DateJoined = DateTime.Now;
//user.HowHearId = Input.HowHearId;
await UserStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
var emailStore = GetEmailStore();
await emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
var result = await UserManager.CreateAsync(user, Input.Password);
if (!result.Succeeded)
{
identityErrors = result.Errors;
return;
}
//Logger.LogInformation("User created a new account with password.");
var userId = await UserManager.GetUserIdAsync(user);
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = NavigationManager.GetUriWithQueryParameters(
NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri,
new Dictionary<string, object?> { ["userId"] = userId, ["code"] = code, ["returnUrl"] = ReturnUrl });
await EmailSender.SendConfirmationLinkAsync(user, Input.Email, HtmlEncoder.Default.Encode(callbackUrl));
if (UserManager.Options.SignIn.RequireConfirmedAccount)
{
RedirectManager.RedirectTo(
"Account/RegisterConfirmation",
new() { ["email"] = Input.Email, ["returnUrl"] = ReturnUrl });
}
await SignInManager.SignInAsync(user, isPersistent: false);
RedirectManager.RedirectTo(ReturnUrl);
}
private ApplicationUser CreateUser()
{
try
{
return Activator.CreateInstance<ApplicationUser>();
}
catch
{
throw new InvalidOperationException($"Can't create an instance of '{nameof(ApplicationUser)}'. " +
$"Ensure that '{nameof(ApplicationUser)}' is not an abstract class and has a parameterless constructor.");
}
}
private IUserEmailStore<ApplicationUser> GetEmailStore()
{
if (!UserManager.SupportsUserEmail)
{
throw new NotSupportedException("The default UI requires a user store with email support.");
}
return (IUserEmailStore<ApplicationUser>)UserStore;
}
private sealed class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
public string Email { get; set; } = "";
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; } = "";
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; } = "";
[Required(ErrorMessage = "Team Supported Required")]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 3)]
[Display(Name = "Team Supported")]
public string? TeamSupported { get; set; }
[Required(ErrorMessage = "Country Required")]
[StringLength(60, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 2)]
public string? Country { get; set; }
[Required]
[Display(Name = "Username")]
[StringLength(20, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 2)]
public string? FHUsername { get; set; } // Used for leaderboard not login
[Display(Name = "X/Twitter Username")]
[StringLength(15, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 0)]
public string? XUsername { get; set; }
[Display(Name = "How did you hear about us?")]
[StringLength(50, ErrorMessage = "Max length of how did you hear about us 50 characters")]
public string HowHearText { get; set; }
// id wont bind just using free text
[Display(Name = "How did you hear about us?")]
//[Range(0, 100, ErrorMessage = "Please select How did you hear about us")]
public int HowHearId { get; set; }
}
}
您应该放置
name
属性,以便 blazor 可以将表单字段与模型的属性相匹配。
<select name="Input.HowHearId" @bind="@Input.HowHearId">
当您使用
<InputSelect>
组件时,这是“自动”的,我推荐它。