我正在為我的 ASP.NET Blazor 服務器應用程式創建一個自定義注冊表單。我已經完成了所有驗證作業,包括使用自定義驗證屬性驗證日期,因此我熟悉該程序。
我陷入困境的部分是電子郵件地址/用戶名的唯一性。如果已經存在具有提供的電子郵件/用戶名的用戶,則 ASP.NET 身份框架回傳一個成功的屬性,該屬性為 false。甚至還有一個有用的描述。不幸的是,這是在表單驗證之后,Blazor 已經確定表單是有效的。
var result = await userManager.CreateAsync(user, _tempPassword);
result.Succeeded = false
result.Errors.Count = 1
result.Errors[0].Description = "Username 'XXX' is already taken."
當資訊在“頁面”上隨時可用時,我必須創建一個復雜的自定義驗證屬性,其中包括依賴注入(用于身份和/或主資料庫),這對我來說似乎很瘋狂。
下面是我的 Blazor 頁面。請參閱方法else
中的宣告HandleValidSubmit
。
@page "/Employee/Create"
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Identity
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject UserManager<ApplicationUser> userManager
@inject NavigationManager NavigationManager
@inject IDataAccess database
<AuthorizeView Roles="Admin" Context="authContext">
<Authorized>
<h3>New Employee</h3>
<EditForm Model="_employee" Context="formContext" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>First Name: <InputText id="firstName" class="rounded-border" @bind-Value="_employee.FirstName" /></p>
<p>Last Name: <InputText id="lastName" class="rounded-border" @bind-Value="_employee.LastName" /></p>
<p>Email: <InputText id="email" class="rounded-border" @bind-Value="_employee.Email" /></p>
<div id="newEmployeeButtons">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</EditForm>
</Authorized>
</AuthorizeView>
@code {
private Employee _employee = new();
protected override void OnInitialized()
{
_employee = new Employee();
}
private async Task HandleValidSubmit()
{
ApplicationUser user = new()
{
FirstName = _employee.FirstName,
LastName = _employee.LastName,
Email = _employee.Email
};
var result = await userManager.CreateAsync(user, _tempPassword);
if (result.Succeeded)
{
// Save to main DB
_employee.Id = await userManager.GetUserIdAsync(user);
await database.CreateEmployeeAsync(_employee);
_employee = new(); // Clear form
}
else
{
// Microsoft.AspNetCore.Identity.IdentityResult returns an error here,
// NOT an exception. The error has a description of "Username 'XXX'
// is already taken."
// HOW DO I TURN THIS INTO A VALIDATION MESSAGE ON THE PAGE?!
// Currently it just fails silently
}
}
}
編輯2:
我決定與其在此處發布代碼段,不如將一個最小的可重現示例推送到 GitHub。
存盤庫位于此處
分支:主
如前所述,該EditContext_OnFieldChanged
方法從未被提出。我在方法的開頭設定了一個斷點,但斷點永遠不會被擊中。由于我設定emailExists = true
了 ,因此驗證應該總是失敗(出于測驗目的)。
分支:noModelAttribute
從組件中移除Model
屬性,但僅在導航到頁面EditForm
時引發例外。/Employee/Create
最終編輯
真正的問題似乎是OnInitialized
方法中的宣告。在導致例外時使用_editContext = new(_employee);
作品。EditContext _editContext = new(_employee);
uj5u.com熱心網友回復:
這是一種方法...
<EditForm EditContext="EditContext" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>First Name: <InputText id="firstName" @bind-Value="_employee.FirstName" /></p>
<p>Last Name: <InputText id="lastName" @bind-Value="_employee.LastName" /></p>
<p>Email: <InputText id="email" @bind-Value="_employee.Email" /></p>
<div id="newEmployeeButtons">
<button type="submit" >Save</button>
</div>
</EditForm>
@code {
private Employee _employee = new();
private EditContext EditContext;
ValidationMessageStore messages;
protected override void OnInitialized()
{
EditContext = new EditContext(_employee);
EditContext.OnFieldChanged = EditContext_OnFieldChanged;
messages = new ValidationMessageStore(EditContext);
}
private void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs e)
{
if (e.FieldIdentifier.FieldName == nameof(_employee.Email))
{
// Perform a database call to verify if the user
// name exists in the database
var _emailExists = MyService.EmailExists(
_employee.Email);
if (_emailExists)
{
messages.Clear(e.FieldIdentifier);
messages.Add(e.FieldIdentifier, "is already taken.");
}
else
{
messages.Clear(e.FieldIdentifier);
}
}
EditContext.NotifyValidationStateChanged();
// var isValid = EditContext.Validate();
// if (isValid)
// {
// this.HandleValidSubmit();
// }
InvokeAsync(() => StateHasChanged());
}
}
注意:您應該在服務中定義 Exists 方法。您不得將UserManager
服務注入到您的組件中。
我很快寫了這段代碼,但我希望你明白了......
更新:
@page "/Employee/Create"
@using BlazorValidation.Data
<h3>New Employee</h3>
<EditForm EditContext="_editContext" Context="formContext" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>First Name: <InputText id="firstName" @bind-Value="_employee.FirstName" /></p>
<p>Last Name: <InputText id="lastName" @bind-Value="_employee.LastName" /></p>
<p>Email: <InputText id="email" @bind-Value="_employee.Email" /></p>
<div id="newEmployeeButtons">
<button type="submit" >Save</button>
</div>
</EditForm>
@code {
private Employee _employee = new();
private EditContext _editContext;
private ValidationMessageStore messages;
protected override void OnInitialized()
{
_editContext = new(_employee);
_editContext.OnFieldChanged = EditContext_OnFieldChanged;
messages = new ValidationMessageStore(_editContext);
}
private void EditContext_OnFieldChanged(object sender, FieldChangedEventArgs args)
{
if (args.FieldIdentifier.FieldName == nameof(_employee.Email))
{
bool emailExists = true;
if (emailExists)
{
messages.Clear(args.FieldIdentifier);
messages.Add(args.FieldIdentifier, "A user with this email address already exists.");
}
else
{
messages.Clear(args.FieldIdentifier);
}
}
_editContext.NotifyValidationStateChanged();
InvokeAsync(() => StateHasChanged());
}
private async Task HandleValidSubmit()
{
Console.WriteLine("Submitting...");
await Task.CompletedTask;
}
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/529927.html
標籤:asp.net 核心验证西装外套.net-6.0blazor 服务器端
上一篇:字串/數字行為不正確的簡單驗證