Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Not
Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.
Bu makalede, formlarda Blazor doğrulamanın nasıl kullanılacağı açıklanmaktadır.
Form doğrulama
Temel form doğrulama senaryolarında, bir EditForm örnek form alanlarını doğrulamak için bildirilen EditContext ve ValidationMessageStore örnekleri kullanabilir. OnValidationRequested olayının işleyicisi, EditContext özel doğrulama mantığını yürütür. İşleyicinin sonucu, ValidationMessageStore örneğini günceller.
Temel form doğrulaması, formun modelinin formu barındıran bileşende doğrudan bileşende veya bir alt sınıfta üye olarak tanımlandığı durumlarda kullanışlıdır. Bağımsız bir model sınıfının çeşitli bileşenler arasında kullanıldığı durumlarda doğrulayıcı bileşeni kullanılması önerilir.
Blazor Web App'lerde, istemci tarafı doğrulama için etkin bir BlazorSignalR devre gerekir. İstemci tarafı doğrulaması, statik sunucu tarafı işlemeyi (statik SSR) benimseyen bileşenlerdeki formlar için kullanılamaz. Statik SSR'yi benimseyen formlar, form gönderildikten sonra sunucuda doğrulanır.
Aşağıdaki bileşende HandleValidationRequested işleyici yöntemi, formu doğrulamadan önce çağırarak ValidationMessageStore.Clear mevcut doğrulama iletilerini temizler.
Starship8.razor:
@page "/starship-8"
@implements IDisposable
@inject ILogger<Starship8> Logger
<h2>Holodeck Configuration</h2>
<EditForm EditContext="editContext" OnValidSubmit="Submit" FormName="Starship8">
<div>
<label>
<InputCheckbox @bind-Value="Model!.Subsystem1" />
Safety Subsystem
</label>
</div>
<div>
<label>
<InputCheckbox @bind-Value="Model!.Subsystem2" />
Emergency Shutdown Subsystem
</label>
</div>
<div>
<ValidationMessage For="() => Model!.Options" />
</div>
<div>
<button type="submit">Update</button>
</div>
</EditForm>
@code {
private EditContext? editContext;
[SupplyParameterFromForm]
private Holodeck? Model { get; set; }
private ValidationMessageStore? messageStore;
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
editContext.OnValidationRequested += HandleValidationRequested;
messageStore = new(editContext);
}
private void HandleValidationRequested(object? sender,
ValidationRequestedEventArgs args)
{
messageStore?.Clear();
// Custom validation logic
if (!Model!.Options)
{
messageStore?.Add(() => Model.Options, "Select at least one.");
}
}
private void Submit() => Logger.LogInformation("Submit: Processing form");
public class Holodeck
{
public bool Subsystem1 { get; set; }
public bool Subsystem2 { get; set; }
public bool Options => Subsystem1 || Subsystem2;
}
public void Dispose()
{
if (editContext is not null)
{
editContext.OnValidationRequested -= HandleValidationRequested;
}
}
}
@page "/starship-8"
@implements IDisposable
@inject ILogger<Starship8> Logger
<h2>Holodeck Configuration</h2>
<EditForm EditContext="editContext" OnValidSubmit="Submit" FormName="Starship8">
<div>
<label>
<InputCheckbox @bind-Value="Model!.Subsystem1" />
Safety Subsystem
</label>
</div>
<div>
<label>
<InputCheckbox @bind-Value="Model!.Subsystem2" />
Emergency Shutdown Subsystem
</label>
</div>
<div>
<ValidationMessage For="() => Model!.Options" />
</div>
<div>
<button type="submit">Update</button>
</div>
</EditForm>
@code {
private EditContext? editContext;
[SupplyParameterFromForm]
private Holodeck? Model { get; set; }
private ValidationMessageStore? messageStore;
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
editContext.OnValidationRequested += HandleValidationRequested;
messageStore = new(editContext);
}
private void HandleValidationRequested(object? sender,
ValidationRequestedEventArgs args)
{
messageStore?.Clear();
// Custom validation logic
if (!Model!.Options)
{
messageStore?.Add(() => Model.Options, "Select at least one.");
}
}
private void Submit() => Logger.LogInformation("Submit: Processing form");
public class Holodeck
{
public bool Subsystem1 { get; set; }
public bool Subsystem2 { get; set; }
public bool Options => Subsystem1 || Subsystem2;
}
public void Dispose()
{
if (editContext is not null)
{
editContext.OnValidationRequested -= HandleValidationRequested;
}
}
}
@page "/starship-8"
@implements IDisposable
@inject ILogger<Starship8> Logger
<h2>Holodeck Configuration</h2>
<EditForm EditContext="editContext" OnValidSubmit="Submit">
<div>
<label>
<InputCheckbox @bind-Value="Model!.Subsystem1" />
Safety Subsystem
</label>
</div>
<div>
<label>
<InputCheckbox @bind-Value="Model!.Subsystem2" />
Emergency Shutdown Subsystem
</label>
</div>
<div>
<ValidationMessage For="() => Model!.Options" />
</div>
<div>
<button type="submit">Update</button>
</div>
</EditForm>
@code {
private EditContext? editContext;
public Holodeck? Model { get; set; }
private ValidationMessageStore? messageStore;
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
editContext.OnValidationRequested += HandleValidationRequested;
messageStore = new(editContext);
}
private void HandleValidationRequested(object? sender,
ValidationRequestedEventArgs args)
{
messageStore?.Clear();
// Custom validation logic
if (!Model!.Options)
{
messageStore?.Add(() => Model.Options, "Select at least one.");
}
}
private void Submit()
{
Logger.LogInformation("Submit called: Processing the form");
}
public class Holodeck
{
public bool Subsystem1 { get; set; }
public bool Subsystem2 { get; set; }
public bool Options => Subsystem1 || Subsystem2;
}
public void Dispose()
{
if (editContext is not null)
{
editContext.OnValidationRequested -= HandleValidationRequested;
}
}
}
Veri Açıklamaları Doğrulayıcı bileşeni ve özelleştirilmiş doğrulama
Bileşen, DataAnnotationsValidator basamaklı EditContextbir öğesine veri ek açıklamaları doğrulaması ekler. Ek açıklama doğrulamasını etkinleştirmek için DataAnnotationsValidator bileşeni gerekir. Veri ek açıklamalarından farklı bir doğrulama sistemi kullanmak için bileşen yerine DataAnnotationsValidator özel bir uygulama kullanın. için DataAnnotationsValidator çerçeve uygulamaları, başvuru kaynağında inceleme için kullanılabilir:
Doğrulama davranışı hakkında ayrıntılı bilgi için doğrulama davranışı bölümüne bakınDataAnnotationsValidator.
Koddaki bir EditContext için veri açıklamaları doğrulama desteğini etkinleştirmeniz gerekiyorsa, enjekte edilmiş bir EnableDataAnnotationsValidation (IServiceProvider) kullanarak @inject IServiceProvider ServiceProviderüzerinde EditContext'i çağırın. Gelişmiş bir örnek için, ASP.NET Core NotifyPropertyChangedValidationComponent çerçevesinin Blazor (BasicTestApp GitHub deposu) dotnet/aspnetcore bileşenine bakın. Örneğin üretim sürümünde, hizmet sağlayıcısı için new TestServiceProvider() bağımsız değişkenini enjeksiyonla eklenen IServiceProviderile değiştirin.
Not
.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).
Blazor iki tür doğrulama gerçekleştirir:
- Alan doğrulaması , kullanıcı bir alanın dışına çıktığında gerçekleştirilir. Alan doğrulama sırasında bileşen, DataAnnotationsValidator bildirilen tüm doğrulama sonuçlarını alanla ilişkilendirir.
- Kullanıcı formu gönderdiğinde model doğrulaması gerçekleştirilir. Model doğrulama sırasında bileşen, DataAnnotationsValidator doğrulama sonucunun rapor verdiği üye adına göre alanı belirlemeye çalışır. Tek bir üyeyle ilişkilendirilmeyen doğrulama sonuçları alan yerine modelle ilişkilendirilir.
Özel doğrulama senaryolarında:
- Doğrulama, bir formun ValidationMessageStore'i için EditContext'ı yönetir.
- DataAnnotationsValidator bileşeni, doğrulama özniteliklerini (veri ek açıklamaları) temel alan formlara doğrulama desteği eklemek için kullanılır.
Özel doğrulamaya ulaşmak için bu makalenin sonraki iki bölümünde açıklanan iki genel yaklaşım vardır:
-
OnValidationRequestedolaykullanarak el ile doğrulama: OnValidationRequested olayına atanmış bir olay işleyicisi aracılığıyla doğrulama istendiğinde, veri ek açıklamaları ve özel kod ile formun alanlarını manuel olarak doğrulayın. - Doğrulayıcı bileşenleri: Bir veya daha fazla özel doğrulayıcı bileşeni, farklı form işleme adımlarında (örneğin, istemci doğrulamasının ardından sunucu doğrulaması) aynı sayfadaki veya aynı formdaki farklı formlar için doğrulamayı işlemek için kullanılabilir.
OnValidationRequested olayını kullanarak el ile doğrulama
EditContext.OnValidationRequestedyönetmek için formu ValidationMessageStore olayına atanmış özel bir olay işleyicisi ile el ile doğrulayabilirsiniz.
Blazor çerçevesi, DataAnnotationsValidatordoğrulama özniteliklerine (veri ek açıklamaları) dayalı formlara ek doğrulama desteği eklemek için bileşeni sağlar.
Önceki Starship8 bileşen örneğini hatırlayarak, HandleValidationRequested yöntemi OnValidationRequested'e atanır ve burada C# kodunda el ile doğrulama gerçekleştirebilirsiniz. Bazı değişiklikler, DataAnnotationsValidator ve Holodeck modeline uygulanan doğrulama özniteliği aracılığıyla veri ek açıklamaları doğrulaması ile mevcut manuel doğrulamayı nasıl birleştirdiğini gösterir.
Bileşen tanım dosyasının üst kısmındaki bileşenin System.ComponentModel.DataAnnotations yönergelerinde Razor ad alanına başvurun:
@using System.ComponentModel.DataAnnotations
Dizenin uzunluğunu altı karakterle sınırlamak için doğrulama özniteliğiyle Id modeline bir Holodeck özelliği ekleyin:
[StringLength(6)]
public string? Id { get; set; }
Forma bir DataAnnotationsValidator bileşeni (<DataAnnotationsValidator />) ekleyin. Genellikle bileşen hemen <EditForm> etiketinin altına yerleştirilir, ancak bunu formda herhangi bir yere yerleştirebilirsiniz:
<DataAnnotationsValidator />
<EditForm> etiketindeki formun gönderme davranışını OnSubmit'den OnValidSubmit'ye değiştirin, bu da atanan olay işleyicisi yöntemini yürütmeden önce formun geçerli olmasını sağlar.
- OnSubmit="Submit"
+ OnValidSubmit="Submit"
<EditForm>içinde, Id özelliği için bir alan ekleyin:
<div>
<label>
<InputText @bind-Value="Model!.Id" />
ID (6 characters max)
</label>
<ValidationMessage For="() => Model!.Id" />
</div>
Önceki değişiklikleri yaptıktan sonra formun davranışı aşağıdaki belirtim ile eşleşir:
-
Idalanı yalnızca odağı kaybettiğinde,Idözelliğindeki veri açıklamaları doğrulaması bir doğrulama hatası oluşturmaz. KullanıcıUpdatedüğmesini seçtiğinde doğrulama yürütülür. - Formun
HandleValidationRequestedolayına atanan OnValidationRequested yönteminde gerçekleştirmek istediğiniz tüm el ile doğrulamalar, kullanıcı formunUpdatedüğmesini seçtiğinde yürütülür.Starship8bileşeni örneğinin mevcut kodunda, kullanıcının formu doğrulamak için onay kutularından birini veya her ikisini de seçmesi gerekir. - Form, hem veri ek açıklamaları hem de el ile doğrulama geçene kadar
Submityöntemini işlemez.
Doğrulayıcı bileşenleri
Doğrulayıcı bileşenler, bir formun ValidationMessageStore öğesini EditContext yöneterek form doğrulamasını destekler.
Çerçeve, Blazor doğrulama özniteliklerine DataAnnotationsValidator (veri ek açıklamaları) göre formlara doğrulama desteği eklemek için bileşen sağlar. Farklı form işleme adımlarında (örneğin, istemci doğrulamasının ardından sunucu doğrulaması) aynı sayfada veya aynı formda farklı formlar için doğrulama iletilerini işlemek için özel doğrulayıcı bileşenleri oluşturabilirsiniz. Bu bölümde gösterilen doğrulayıcı bileşeni örneği, CustomValidationbu makalenin aşağıdaki bölümlerinde kullanılır:
Yerleşik veri ek açıklaması doğrulayıcıları içinde yalnızca [Remote] doğrulama özniteliği desteklenmezBlazor.
Not
Birçok durumda özel doğrulayıcı bileşenleri yerine özel veri ek açıklaması doğrulama öznitelikleri kullanılabilir. Formun modeline uygulanan özel öznitelikler, bileşenin DataAnnotationsValidator kullanımıyla etkinleştirilir. Sunucu doğrulaması ile kullanıldığında, modele uygulanan tüm özel özniteliklerin sunucuda yürütülebilir olması gerekir. Daha fazla bilgi için Özel doğrulama öznitelikleri bölümüne bakın.
adresinden ComponentBasebir doğrulayıcı bileşeni oluşturun:
- Formunki EditContext , bileşenin basamaklı bir parametresidir .
- Doğrulayıcı bileşeni başlatıldığında, form hatalarının güncel bir listesini tutmak için yeni bir ValidationMessageStore oluşturulur.
- Formun bileşenindeki geliştirici kodu yöntemini çağırdığında
DisplayErrorsileti deposu hata alır. HatalarDisplayErrorsyöntemineDictionary<string, List<string>>olarak aktarılır. Sözlükte anahtar, bir veya daha fazla hatası olan form alanının adıdır. Değer hata listesidir. - Aşağıdakilerden herhangi biri oluştuğunda iletiler temizlenir:
- EditContext olayı tetiklendiğinde OnValidationRequested üzerinde doğrulama istenir. Tüm hatalar temizlenir.
- Olay OnFieldChanged tetiklendiğinde formda bir alan değişir. Yalnızca alanın hataları temizlenir.
-
ClearErrorsyöntemi geliştirici kodu tarafından çağrılır. Tüm hatalar temizlenir.
Aşağıdaki sınıftaki ad alanını uygulamanızın ad alanıyla eşleşecek şekilde güncelleştirin.
CustomValidation.cs:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
namespace BlazorSample;
public class CustomValidation : ComponentBase
{
private ValidationMessageStore? messageStore;
[CascadingParameter]
private EditContext? CurrentEditContext { get; set; }
protected override void OnInitialized()
{
if (CurrentEditContext is null)
{
throw new InvalidOperationException(
$"{nameof(CustomValidation)} requires a cascading " +
$"parameter of type {nameof(EditContext)}. " +
$"For example, you can use {nameof(CustomValidation)} " +
$"inside an {nameof(EditForm)}.");
}
messageStore = new(CurrentEditContext);
CurrentEditContext.OnValidationRequested += (s, e) =>
messageStore?.Clear();
CurrentEditContext.OnFieldChanged += (s, e) =>
messageStore?.Clear(e.FieldIdentifier);
}
public void DisplayErrors(Dictionary<string, List<string>> errors)
{
if (CurrentEditContext is not null)
{
foreach (var err in errors)
{
messageStore?.Add(CurrentEditContext.Field(err.Key), err.Value);
}
CurrentEditContext.NotifyValidationStateChanged();
}
}
public void ClearErrors()
{
messageStore?.Clear();
CurrentEditContext?.NotifyValidationStateChanged();
}
}
Önemli
türetilirken bir ad alanı belirtmek ComponentBase. Ad alanı belirtilememek derleme hatasıyla sonuçlanır:
Tag helpers cannot target tag name '<global namespace>.{CLASS NAME}' because it contains a ' ' character.
{CLASS NAME} yer tutucu, bileşen sınıfının adıdır. Bu bölümdeki özel doğrulayıcı örneği, örnek ad alanını BlazorSamplebelirtir.
Not
Anonim lambda ifadeleri, önceki örnekte OnValidationRequested ve OnFieldChanged için kayıtlı olay işleyicileridir. Bu senaryoda IDisposable uygulanması ve olay temsilcilerinin abonelikten kaldırılması gerekmez. Daha fazla bilgi için bkz. ASP.NET Core Razor bileşen imhası.
Doğrulayıcı bileşeniyle iş mantığı doğrulaması
Genel iş mantığı doğrulaması için, bir sözlükte form hataları alan bir doğrulayıcı bileşeni kullanın.
Temel doğrulama, formun modelinin, doğrudan bileşende veya bir alt sınıfta üye olarak formu barındıran bileşen içinde tanımlandığı durumlarda kullanışlıdır. Bağımsız bir model sınıfının çeşitli bileşenler arasında kullanıldığı durumlarda doğrulayıcı bileşeni kullanılması önerilir.
Aşağıdaki örnekte:
- "Giriş bileşenleri makalesinin
Starfleet Starship DatabasebölümününStarship3formunun ( bileşeni) yalnızca yıldızgeminin sınıflandırmasını ve açıklamasını kabul eden kısaltılmış bir sürümü kullanılır." Bileşen forma dahil edilmediğinden, form gönderildiğinde veri açıklamalarının doğrulaması tetiklenmez. - Bu
CustomValidationmakalenin Validator bileşenleri bölümünde yer alan bileşen kullanılır. - Doğrulama, kullanıcı "
Description" gemi sınıflandırmasını (Defense) seçerse, geminin açıklaması (Classification) için bir değer gerektirir.
Bileşende doğrulama iletileri ayarlandığında, bunlar doğrulayıcıya ValidationMessageStore eklenir ve 'nin doğrulama özetinde EditFormgösterilir.
Starship9.razor:
@page "/starship-9"
@inject ILogger<Starship9> Logger
<h1>Starfleet Starship Database</h1>
<h2>New Ship Entry Form</h2>
<EditForm Model="Model" OnValidSubmit="Submit" FormName="Starship9">
<CustomValidation @ref="customValidation" />
<ValidationSummary />
<div>
<label>
Primary Classification:
<InputSelect @bind-Value="Model!.Classification">
<option value="">
Select classification ...
</option>
<option checked="@(Model!.Classification == "Exploration")"
value="Exploration">
Exploration
</option>
<option checked="@(Model!.Classification == "Diplomacy")"
value="Diplomacy">
Diplomacy
</option>
<option checked="@(Model!.Classification == "Defense")"
value="Defense">
Defense
</option>
</InputSelect>
</label>
</div>
<div>
<label>
Description (optional):
<InputTextArea @bind-Value="Model!.Description" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
private CustomValidation? customValidation;
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() =>
Model ??= new() { ProductionDate = DateTime.UtcNow };
private void Submit()
{
customValidation?.ClearErrors();
var errors = new Dictionary<string, List<string>>();
if (Model!.Classification == "Defense" &&
string.IsNullOrEmpty(Model.Description))
{
errors.Add(nameof(Model.Description),
[ "For a 'Defense' ship classification, " +
"'Description' is required." ]);
}
if (errors.Any())
{
customValidation?.DisplayErrors(errors);
}
else
{
Logger.LogInformation("Submit called: Processing the form");
}
}
}
@page "/starship-9"
@inject ILogger<Starship9> Logger
<h1>Starfleet Starship Database</h1>
<h2>New Ship Entry Form</h2>
<EditForm Model="Model" OnValidSubmit="Submit" FormName="Starship9">
<CustomValidation @ref="customValidation" />
<ValidationSummary />
<div>
<label>
Primary Classification:
<InputSelect @bind-Value="Model!.Classification">
<option value="">
Select classification ...
</option>
<option checked="@(Model!.Classification == "Exploration")"
value="Exploration">
Exploration
</option>
<option checked="@(Model!.Classification == "Diplomacy")"
value="Diplomacy">
Diplomacy
</option>
<option checked="@(Model!.Classification == "Defense")"
value="Defense">
Defense
</option>
</InputSelect>
</label>
</div>
<div>
<label>
Description (optional):
<InputTextArea @bind-Value="Model!.Description" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
private CustomValidation? customValidation;
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() =>
Model ??= new() { ProductionDate = DateTime.UtcNow };
private void Submit()
{
customValidation?.ClearErrors();
var errors = new Dictionary<string, List<string>>();
if (Model!.Classification == "Defense" &&
string.IsNullOrEmpty(Model.Description))
{
errors.Add(nameof(Model.Description),
[ "For a 'Defense' ship classification, " +
"'Description' is required." ]);
}
if (errors.Any())
{
customValidation?.DisplayErrors(errors);
}
else
{
Logger.LogInformation("Submit called: Processing the form");
}
}
}
@page "/starship-9"
@inject ILogger<Starship9> Logger
<h1>Starfleet Starship Database</h1>
<h2>New Ship Entry Form</h2>
<EditForm Model="Model" OnValidSubmit="Submit">
<CustomValidation @ref="customValidation" />
<ValidationSummary />
<div>
<label>
Primary Classification:
<InputSelect @bind-Value="Model!.Classification">
<option value="">Select classification ...</option>
<option value="Exploration">Exploration</option>
<option value="Diplomacy">Diplomacy</option>
<option value="Defense">Defense</option>
</InputSelect>
</label>
</div>
<div>
<label>
Description (optional):
<InputTextArea @bind-Value="Model!.Description" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
private CustomValidation? customValidation;
public Starship? Model { get; set; }
protected override void OnInitialized() =>
Model ??= new() { ProductionDate = DateTime.UtcNow };
private void Submit()
{
customValidation?.ClearErrors();
var errors = new Dictionary<string, List<string>>();
if (Model!.Classification == "Defense" &&
string.IsNullOrEmpty(Model.Description))
{
errors.Add(nameof(Model.Description),
new() { "For a 'Defense' ship classification, " +
"'Description' is required." });
}
if (errors.Any())
{
customValidation?.DisplayErrors(errors);
}
else
{
Logger.LogInformation("Submit called: Processing the form");
}
}
}
Not
Doğrulama bileşenlerini kullanmaya alternatif olarak, veri ek açıklaması doğrulama öznitelikleri kullanılabilir. Formun modeline uygulanan özel öznitelikler, bileşenin DataAnnotationsValidator kullanımıyla etkinleştirilir. Sunucu doğrulaması ile kullanıldığında özniteliklerin sunucuda yürütülebilir olması gerekir. Daha fazla bilgi için Özel doğrulama öznitelikleri bölümüne bakın.
Doğrulayıcı bileşeniyle sunucu doğrulaması
Bu bölüm senaryolara odaklanmıştır Blazor Web App ancak web API'siyle sunucu doğrulaması kullanan her tür uygulama için yaklaşım aynı genel yaklaşımı benimser.
Bu bölüm barındırılan Blazor WebAssembly senaryolara odaklanmıştır, ancak web API'siyle sunucu doğrulaması kullanan her tür uygulama için yaklaşım aynı genel yaklaşımı benimser.
sunucu doğrulaması, istemci doğrulamasına ek olarak desteklenir:
- Formda istemci doğrulamasını DataAnnotationsValidator bileşeni ile işleyin.
- Form istemci doğrulamasını (OnValidSubmit çağrılır) geçtiğinde EditContext.Model , form işleme için bir arka uç sunucu API'sine gönderin.
- Sunucuda model doğrulama işlemini gerçekleştirme.
- Sunucu API'sinde hem yerleşik çerçeve veri ek açıklamaları doğrulaması hem de geliştirici tarafından sağlanan özel doğrulama mantığı bulunur. Doğrulama sunucudan geçerse formu işleyin ve bir başarı durumu kodu (
200 - OK) geri gönderin. Doğrulama başarısız olursa, bir hata durum kodu (400 - Bad Request) ve alan doğrulama hataları döndürür. - Formu başarılı olduğunda devre dışı bırakın veya hataları görüntüleyin.
Temel doğrulama, formun modelinin, doğrudan bileşende veya bir alt sınıfta üye olarak formu barındıran bileşen içinde tanımlandığı durumlarda kullanışlıdır. Bağımsız bir model sınıfının çeşitli bileşenler arasında kullanıldığı durumlarda doğrulayıcı bileşeni kullanılması önerilir.
Aşağıdaki örnek aşağıdakileri temel alır:
- Etkileşimli WebAssembly bileşenleri içeren bir
, proje şablonundan oluşturulmuştur . -
Starshipmodeli (Starship.cs) Örnek form bölümünün Giriş bileşenleri makalesinde. -
CustomValidationDoğrulayıcı bileşenleri bölümünde gösterilen bileşen.
Starship Hem istemci hem de sunucu projelerinin modeli kullanabilmesi için modeli (Starship.cs) paylaşılan bir sınıf kitaplığı projesine yerleştirin. Ad alanını paylaşılan uygulamanın ad alanıyla eşleşecek şekilde ekleyin veya güncelleştirin (örneğin, namespace BlazorSample.Shared). Model veri ek açıklamaları gerektirdiğinden, paylaşılan sınıf kitaplığının paylaşılan çerçeveyi kullandığını onaylayın veya paketi paylaşılan projeye ekleyin System.ComponentModel.Annotations .
Not
.NET uygulamalarına paket ekleme hakkında yönergeler için, Paket tüketimi iş akışında (NuGet belgeleri)paketleri yüklemek ve yönetmek altındaki makalelere bakın. NuGet.org'da doğru paket sürümlerini onaylayın.
ana projesinde Blazor Web App, yıldız gemisi doğrulama isteklerini işlemek ve başarısız doğrulama iletilerini döndürmek için bir denetleyici ekleyin. Son using deyimde paylaşılan sınıf kitaplığı projesi için ve denetleyici sınıfı için namespace ad alanlarını güncelleştirin. İstemci ve sunucu veri ek açıklamaları doğrulamasına ek olarak, kullanıcı gemi sınıflandırmasınıDescription () seçerse denetleyici, geminin açıklaması (Defense) için bir değer sağlandığını doğrularClassification.
- Barındırılan bir
çözüm ,proje şablonundan oluşturulmuştur . Bu yaklaşım, barındırılan Blazor güvenlik belgelerinde açıklanan güvenli barındırılan Blazor WebAssemblyçözümlerden herhangi biri için desteklenir. -
Starshipmodeli (Starship.cs) Örnek form bölümünün Giriş bileşenleri makalesinde. -
CustomValidationDoğrulayıcı bileşenleri bölümünde gösterilen bileşen.
Starship Hem istemci hem de sunucu uygulamalarının modeli kullanabilmesi Starship.cs için modeli (Shared) çözümün projesine yerleştirin. Ad alanını paylaşılan uygulamanın ad alanıyla eşleşecek şekilde ekleyin veya güncelleştirin (örneğin, namespace BlazorSample.Shared). Model için veri ek açıklamaları gerektiğinden System.ComponentModel.Annotations paketi Shared projeye ekleyin.
Not
.NET uygulamalarına paket ekleme hakkında yönergeler için, Paket tüketimi iş akışında (NuGet belgeleri)paketleri yüklemek ve yönetmek altındaki makalelere bakın. NuGet.org'da doğru paket sürümlerini onaylayın.
Projede Server , yıldız gemisi doğrulama isteklerini işlemek ve başarısız doğrulama iletilerini döndürmek için bir denetleyici ekleyin. Projenin using ve denetleyici sınıfının son Shared deyimindeki namespace ad alanlarını güncelleştirin. İstemci ve sunucu veri ek açıklamaları doğrulamasına ek olarak, kullanıcı gemi sınıflandırmasınıDescription () seçerse denetleyici, geminin açıklaması (Defense) için bir değer sağlandığını doğrularClassification.
Form sunucuya gönderildiğinde istemci tarafında aynı doğrulama yapılmadığından, gemi sınıflandırması için doğrulama yalnızca denetleyicideki Defense sunucuda gerçekleşir. İstemci doğrulaması olmadan sunucu doğrulaması, sunucudaki kullanıcı girişinin özel iş mantığı doğrulaması gerektiren uygulamalarda yaygındır. Örneğin, kullanıcı girişini doğrulamak için bir kullanıcı için depolanan verilerden özel bilgiler gerekebilir. Özel veriler açıkça istemci doğrulaması için istemciye gönderilemiyor.
Not
StarshipValidation Bu bölümdeki denetleyici Microsoft Identity 2.0 kullanır. Web API'si yalnızca bu API için "API.Access" kapsamına sahip kullanıcılar için belirteçleri kabul eder. API'nin kapsam adı ile API.Accessfarklıysa ek özelleştirme gerekir.
Güvenlik hakkında daha fazla bilgi için bkz:
- ASP.NET Çekirdek Blazor kimlik doğrulaması ve yetkilendirme (ve Güvenlik ve Blazor düğümdeki Identitydiğer makaleler)
- Microsoft kimlik platformu belgeleri
Controllers/StarshipValidation.cs:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BlazorSample.Shared;
namespace BlazorSample.Server.Controllers;
[Authorize]
[ApiController]
[Route("[controller]")]
public class StarshipValidationController(
ILogger<StarshipValidationController> logger)
: ControllerBase
{
static readonly string[] scopeRequiredByApi = [ "API.Access" ];
[HttpPost]
public async Task<IActionResult> Post(Starship model)
{
HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);
try
{
if (model.Classification == "Defense" &&
string.IsNullOrEmpty(model.Description))
{
ModelState.AddModelError(nameof(model.Description),
"For a 'Defense' ship " +
"classification, 'Description' is required.");
}
else
{
logger.LogInformation("Processing the form asynchronously");
// async ...
return Ok(ModelState);
}
}
catch (Exception ex)
{
logger.LogError("Validation Error: {Message}", ex.Message);
}
return BadRequest(ModelState);
}
}
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BlazorSample.Shared;
namespace BlazorSample.Server.Controllers;
[Authorize]
[ApiController]
[Route("[controller]")]
public class StarshipValidationController(
ILogger<StarshipValidationController> logger)
: ControllerBase
{
static readonly string[] scopeRequiredByApi = new[] { "API.Access" };
[HttpPost]
public async Task<IActionResult> Post(Starship model)
{
HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);
try
{
if (model.Classification == "Defense" &&
string.IsNullOrEmpty(model.Description))
{
ModelState.AddModelError(nameof(model.Description),
"For a 'Defense' ship " +
"classification, 'Description' is required.");
}
else
{
logger.LogInformation("Processing the form asynchronously");
// async ...
return Ok(ModelState);
}
}
catch (Exception ex)
{
logger.LogError("Validation Error: {Message}", ex.Message);
}
return BadRequest(ModelState);
}
}
Önceki denetleyicinin (BlazorSample.Server.Controllers) ad alanını, uygulamanın denetleyicilerinin ad alanıyla eşleşecek şekilde onaylayın veya güncelleştirin.
Sunucuda model bağlama doğrulama hatası oluştuğunda, bir ApiController (ApiControllerAttribute) genellikle varsayılan bir hatalı istek yanıtı ile ValidationProblemDetails döndürür. Aşağıdaki örnekte gösterildiği gibi, formun tüm alanları gönderilmediğinde ve form doğrulamada başarısız olduğunda yanıt yalnızca doğrulama hatalarından Starfleet Starship Database daha fazla veri içerir:
{
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"Id": [ "The Id field is required." ],
"Classification": [ "The Classification field is required." ],
"IsValidatedDesign": [ "This form disallows unapproved ships." ],
"MaximumAccommodation": [ "Accommodation invalid (1-100000)." ]
}
}
Not
Yukarıdaki JSON yanıtını göstermek için formun istemci doğrulamasını devre dışı bırakarak boş alan formu göndermeye izin vermelisiniz veya Firefox Browser Developer gibi sunucu API'sine doğrudan istek göndermek için bir araç kullanmalısınız.
Sunucu API'si önceki varsayılan JSON yanıtını döndürürse istemcinin yanıtı geliştirici kodunda ayrıştırarak form doğrulama hatası işleme için düğümün errors alt öğelerini alması mümkündür. Dosyayı ayrıştırmak için geliştirici kodu yazmak uygun değildir. JSON'u elle ayrıştırmak, Dictionary<string, List<string>> çağrıldıktan sonra hataların ReadFromJsonAsyncda ele alınmasını gerektirir. İdeal olarak, aşağıdaki örnekte gösterildiği gibi sunucu API'sinin yalnızca doğrulama hatalarını döndürmesi gerekir:
{
"Id": [ "The Id field is required." ],
"Classification": [ "The Classification field is required." ],
"IsValidatedDesign": [ "This form disallows unapproved ships." ],
"MaximumAccommodation": [ "Accommodation invalid (1-100000)." ]
}
Sunucu API'sinin yanıtını yalnızca doğrulama hatalarını döndürecek şekilde değiştirmek için, ApiControllerAttribute ile açıklanan eylemler üzerinde çağrılan temsilciyi Program dosyasında değiştirin. API uç noktası /StarshipValidation için, BadRequestObjectResult ile birlikte bir ModelStateDictionary döndürün. Diğer API uç noktaları için, varsayılan davranışı yeni ValidationProblemDetails ile nesne sonucunu döndürerek koruyun.
ad alanını Microsoft.AspNetCore.Mvc dosyasının Program ana projesindeki Blazor Web Appdosyanın en üstüne ekleyin:
using Microsoft.AspNetCore.Mvc;
Program dosyasında, aşağıdaki AddControllersWithViews uzantı yöntemini ekleyin veya güncelleştirin ve ConfigureApiBehaviorOptions öğesine aşağıdaki çağrıyı ekleyin:
builder.Services.AddControllersWithViews()
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
if (context.HttpContext.Request.Path == "/StarshipValidation")
{
return new BadRequestObjectResult(context.ModelState);
}
else
{
return new BadRequestObjectResult(
new ValidationProblemDetails(context.ModelState));
}
};
});
Eğer denetleyicilerini ilk kez ana proje Blazor Web App'ye ekliyorsanız, denetleyiciler için hizmetleri kaydeden kodu yerleştirirken denetleyici uç noktalarını eşleyin. Aşağıdaki örnek varsayılan denetleyici yollarını kullanır:
app.MapDefaultControllerRoute();
Not
Önceki örnek, AddControllersWithViews çağrısı yaparak Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını otomatik olarak azaltmak için denetleyici hizmetlerini açıkça kaydeder. Yalnızca AddControllers kullanırsanız, kimlik doğrulama sahteciliği koruması otomatik olarak etkinleştirilmez.
Denetleyici yönlendirme ve doğrulama hatası hata yanıtları hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın:
Proje .Client'nda, CustomValidation bölümünde gösterilen bileşenini ekleyin. Ad alanını uygulamayla eşleşecek şekilde güncelleştirin (örneğin, namespace BlazorSample.Client).
Projede .Client formu, Starfleet Starship Database bileşeninin yardımıyla sunucu doğrulama hatalarını gösterecek şekilde güncellenir. Sunucu API'sinin doğrulama iletileri döndürdüğünde, bunlar bileşenin CustomValidationValidationMessageStoreöğesine eklenir. Formun doğrulama özeti tarafından görüntülenmek üzere hatalar formun EditContext içinde mevcuttur.
Aşağıdaki bileşende, paylaşılan projenin ad alanını (@using BlazorSample.Shared) paylaşılan projenin ad alanına güncelleştirin. Formun yetkilendirme gerektirdiğini, bu nedenle kullanıcının forma gitmek için uygulamada oturum açması gerektiğini unutmayın.
Microsoft.AspNetCore.Mvc uygulamasındaki Program dosyasının en üstüne Server ad alanını ekleyin:
using Microsoft.AspNetCore.Mvc;
Program dosyasında AddControllersWithViews uzantı yöntemini bulun ve ConfigureApiBehaviorOptions öğesine aşağıdaki çağrıyı ekleyin:
builder.Services.AddControllersWithViews()
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
if (context.HttpContext.Request.Path == "/StarshipValidation")
{
return new BadRequestObjectResult(context.ModelState);
}
else
{
return new BadRequestObjectResult(
new ValidationProblemDetails(context.ModelState));
}
};
});
Not
Önceki örnek, AddControllersWithViews çağrısı yaparak Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını otomatik olarak azaltmak için denetleyici hizmetlerini açıkça kaydeder. Yalnızca AddControllers kullanırsanız, kimlik doğrulama sahteciliği koruması otomatik olarak etkinleştirilmez.
Proje Client'nda, CustomValidation bölümünde gösterilen bileşenini ekleyin. Ad alanını uygulamayla eşleşecek şekilde güncelleştirin (örneğin, namespace BlazorSample.Client).
Projede Client formu, Starfleet Starship Database bileşeninin yardımıyla sunucu doğrulama hatalarını gösterecek şekilde güncellenir. Sunucu API'sinin doğrulama iletileri döndürdüğünde, bunlar bileşenin CustomValidationValidationMessageStoreöğesine eklenir. Formun doğrulama özeti tarafından görüntülenmek üzere hatalar formun EditContext içinde mevcuttur.
Aşağıdaki bileşende, projenin ad alanını Shared (@using BlazorSample.Shared) paylaşılan projenin ad alanına güncelleştirin. Formun yetkilendirme gerektirdiğini, bu nedenle kullanıcının forma gitmek için uygulamada oturum açması gerektiğini unutmayın.
Starship10.razor:
Not
EditForm'e dayalı formlar, antiforgery desteğini otomatik olarak etkinleştirir. Denetleyici, denetleyici hizmetlerini kaydetmek ve web API'sine yönelik kötü amaçlı yazılımdan koruma desteğini otomatik olarak etkinleştirmek için kullanmalıdır AddControllersWithViews .
@page "/starship-10"
@rendermode InteractiveWebAssembly
@using System.Net
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using BlazorSample.Shared
@attribute [Authorize]
@inject HttpClient Http
@inject ILogger<Starship10> Logger
<h1>Starfleet Starship Database</h1>
<h2>New Ship Entry Form</h2>
<EditForm FormName="Starship10" Model="Model" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<CustomValidation @ref="customValidation" />
<ValidationSummary />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" disabled="@disabled" />
</label>
</div>
<div>
<label>
Description (optional):
<InputTextArea @bind-Value="Model!.Description"
disabled="@disabled" />
</label>
</div>
<div>
<label>
Primary Classification:
<InputSelect @bind-Value="Model!.Classification" disabled="@disabled">
<option value="">Select classification ...</option>
<option value="Exploration">Exploration</option>
<option value="Diplomacy">Diplomacy</option>
<option value="Defense">Defense</option>
</InputSelect>
</label>
</div>
<div>
<label>
Maximum Accommodation:
<InputNumber @bind-Value="Model!.MaximumAccommodation"
disabled="@disabled" />
</label>
</div>
<div>
<label>
Engineering Approval:
<InputCheckbox @bind-Value="Model!.IsValidatedDesign"
disabled="@disabled" />
</label>
</div>
<div>
<label>
Production Date:
<InputDate @bind-Value="Model!.ProductionDate" disabled="@disabled" />
</label>
</div>
<div>
<button type="submit" disabled="@disabled">Submit</button>
</div>
<div style="@messageStyles">
@message
</div>
</EditForm>
@code {
private CustomValidation? customValidation;
private bool disabled;
private string? message;
private string messageStyles = "visibility:hidden";
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() =>
Model ??= new() { ProductionDate = DateTime.UtcNow };
private async Task Submit(EditContext editContext)
{
customValidation?.ClearErrors();
try
{
using var response = await Http.PostAsJsonAsync<Starship>(
"StarshipValidation", (Starship)editContext.Model);
var errors = await response.Content
.ReadFromJsonAsync<Dictionary<string, List<string>>>() ??
new Dictionary<string, List<string>>();
if (response.StatusCode == HttpStatusCode.BadRequest &&
errors.Any())
{
customValidation?.DisplayErrors(errors);
}
else if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(
$"Validation failed. Status Code: {response.StatusCode}");
}
else
{
disabled = true;
messageStyles = "color:green";
message = "The form has been processed.";
}
}
catch (AccessTokenNotAvailableException ex)
{
ex.Redirect();
}
catch (Exception ex)
{
Logger.LogError("Form processing error: {Message}", ex.Message);
disabled = true;
messageStyles = "color:red";
message = "There was an error processing the form.";
}
}
}
Bir .Client projesi olan Blazor Web App, arka uç web API denetleyicisine HTTP POST istekleri için bir HttpClient de kaydetmelidir. Projenin .Client dosyasına aşağıdakileri Program onaylayın veya ekleyin:
builder.Services.AddScoped(sp =>
new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
Önceki örnek, genellikle ana bilgisayar sayfasındaki builder.HostEnvironment.BaseAddress etiketinin IWebAssemblyHostEnvironment.BaseAddress değerinden türetilen ve uygulamanın temel adresini alan <base> (href) ile temel adresi ayarlar.
@page "/starship-10"
@using System.Net
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using BlazorSample.Shared
@attribute [Authorize]
@inject HttpClient Http
@inject ILogger<Starship10> Logger
<h1>Starfleet Starship Database</h1>
<h2>New Ship Entry Form</h2>
<EditForm Model="Model" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<CustomValidation @ref="customValidation" />
<ValidationSummary />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" disabled="@disabled" />
</label>
</div>
<div>
<label>
Description (optional):
<InputTextArea @bind-Value="Model!.Description"
disabled="@disabled" />
</label>
</div>
<div>
<label>
Primary Classification:
<InputSelect @bind-Value="Model!.Classification" disabled="@disabled">
<option value="">Select classification ...</option>
<option value="Exploration">Exploration</option>
<option value="Diplomacy">Diplomacy</option>
<option value="Defense">Defense</option>
</InputSelect>
</label>
</div>
<div>
<label>
Maximum Accommodation:
<InputNumber @bind-Value="Model!.MaximumAccommodation"
disabled="@disabled" />
</label>
</div>
<div>
<label>
Engineering Approval:
<InputCheckbox @bind-Value="Model!.IsValidatedDesign"
disabled="@disabled" />
</label>
</div>
<div>
<label>
Production Date:
<InputDate @bind-Value="Model!.ProductionDate" disabled="@disabled" />
</label>
</div>
<div>
<button type="submit" disabled="@disabled">Submit</button>
</div>
<div style="@messageStyles">
@message
</div>
</EditForm>
@code {
private CustomValidation? customValidation;
private bool disabled;
private string? message;
private string messageStyles = "visibility:hidden";
public Starship? Model { get; set; }
protected override void OnInitialized() =>
Model ??= new() { ProductionDate = DateTime.UtcNow };
private async Task Submit(EditContext editContext)
{
customValidation?.ClearErrors();
try
{
using var response = await Http.PostAsJsonAsync<Starship>(
"StarshipValidation", (Starship)editContext.Model);
var errors = await response.Content
.ReadFromJsonAsync<Dictionary<string, List<string>>>() ??
new Dictionary<string, List<string>>();
if (response.StatusCode == HttpStatusCode.BadRequest &&
errors.Any())
{
customValidation?.DisplayErrors(errors);
}
else if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(
$"Validation failed. Status Code: {response.StatusCode}");
}
else
{
disabled = true;
messageStyles = "color:green";
message = "The form has been processed.";
}
}
catch (AccessTokenNotAvailableException ex)
{
ex.Redirect();
}
catch (Exception ex)
{
Logger.LogError("Form processing error: {Message}", ex.Message);
disabled = true;
messageStyles = "color:red";
message = "There was an error processing the form.";
}
}
}
Not
Doğrulama bileşeninin kullanımına alternatif olarak, veri notlandırma doğrulama öznitelikleri kullanılabilir. Formun modeline uygulanan özel öznitelikler, bileşenin DataAnnotationsValidator kullanımıyla etkinleştirilir. Sunucu doğrulaması ile kullanıldığında özniteliklerin sunucuda yürütülebilir olması gerekir. Daha fazla bilgi için Özel doğrulama öznitelikleri bölümüne bakın.
Not
Bu bölümdeki sunucu doğrulama yaklaşımı, bu belge kümesindeki barındırılan Blazor WebAssembly çözüm örneklerinden herhangi biri için uygundur:
InputText giriş olayına göre
InputText bileşenini kullanarak, oninput olayını (input) yerine onchange olayını (change) kullanan özel bir bileşen oluşturun.
input Olay kullanımı, her tuş vuruşu üzerinde alan doğrulamasını tetikler.
Aşağıdaki CustomInputText bileşen, çerçevenin InputText bileşenini devralır ve olay bağlamasını oninput (input) ayarlar.
CustomInputText.razor:
@inherits InputText
<input @attributes="AdditionalAttributes"
class="@CssClass"
@bind="CurrentValueAsString"
@bind:event="oninput" />
CustomInputText bileşeni, InputText kullanıldığı her yerde kullanılabilir. Aşağıdaki bileşen paylaşılan CustomInputText bileşeni kullanır.
Starship11.razor:
@page "/starship-11"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship11> Logger
<EditForm Model="Model" OnValidSubmit="Submit" FormName="Starship11">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>
Identifier:
<CustomInputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
<div>
CurrentValue: @Model?.Id
</div>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Submit: Processing form");
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
@page "/starship-11"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship11> Logger
<EditForm Model="Model" OnValidSubmit="Submit" FormName="Starship11">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>
Identifier:
<CustomInputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
<div>
CurrentValue: @Model?.Id
</div>
@code {
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit() => Logger.LogInformation("Submit: Processing form");
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
@page "/starship-11"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship11> Logger
<EditForm Model="Model" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<ValidationSummary />
<CustomInputText @bind-Value="Model!.Id" />
<button type="submit">Submit</button>
</EditForm>
<div>
CurrentValue: @Model?.Id
</div>
@code {
public Starship? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
private void Submit()
{
Logger.LogInformation("Submit called: Processing the form");
}
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
Doğrulama Özeti ve Doğrulama İletisi bileşenleri
BileşenValidationSummary, Doğrulama Özeti Etiketi Yardımcısı'na benzer tüm doğrulama iletilerini özetler:
<ValidationSummary />
Parametresiyle Model belirli bir model için çıkış doğrulama iletileri:
<ValidationSummary Model="Model" />
Bileşen, ValidationMessage<TValue> Doğrulama İletisi Etiketi Yardımcısı'na benzeyen belirli bir alanın doğrulama iletilerini görüntüler. özniteliğiyle For doğrulama alanını ve model özelliğini adlandıran bir lambda ifadesi belirtin:
<ValidationMessage For="@(() => Model!.MaximumAccommodation)" />
ValidationMessage<TValue> ve ValidationSummary bileşenleri rastgele öznitelikleri destekler. Bir bileşen parametresiyle eşleşmeyen tüm öznitelikler, oluşturulan <div> veya <ul> öğesine eklenir.
Uygulamanın stil sayfasında (wwwroot/css/app.css veya wwwroot/css/site.css) doğrulama iletilerinin stilini denetleme. Varsayılan validation-message sınıf, doğrulama iletilerinin metin rengini kırmızıya ayarlar:
.validation-message {
color: red;
}
Form alanının geçerli olup olmadığını belirleme
Doğrulama iletileri almadan bir alanın geçerli olup olmadığını belirlemek için kullanın EditContext.IsValid .
Desteklenir, ancak önerilmez:
var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
Önerilen:
var isValid = editContext.IsValid(fieldIdentifier);
Özel doğrulama öznitelikleri
Özel bir doğrulama özniteliği kullanılırken bir doğrulama sonucunun doğru bir şekilde bir alanla ilişkilendirildiğinden emin olmak için, doğrulama bağlamını öğeyi oluştururken MemberNameValidationResult geçirin.
CustomValidator.cs:
using System;
using System.ComponentModel.DataAnnotations;
public class CustomValidator : ValidationAttribute
{
protected override ValidationResult IsValid(object? value,
ValidationContext validationContext)
{
...
return new ValidationResult("Validation message to user.",
[ validationContext.MemberName! ]);
}
}
using System;
using System.ComponentModel.DataAnnotations;
public class CustomValidator : ValidationAttribute
{
protected override ValidationResult IsValid(object? value,
ValidationContext validationContext)
{
...
return new ValidationResult("Validation message to user.",
new[] { validationContext.MemberName! });
}
}
using System;
using System.ComponentModel.DataAnnotations;
public class CustomValidator : ValidationAttribute
{
protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
{
...
return new ValidationResult("Validation message to user.",
new[] { validationContext.MemberName });
}
}
Özel doğrulama özniteliklerine hizmetleri ValidationContext aracılığıyla ekleyin. Aşağıdaki örnekte, bağımlılık ekleme (DI) ile kullanıcı girişini doğrulayan bir salata şefi formu gösterilmektedir.
SaladChef sınıfı, Ten Forward salatası için onaylanmış yıldız gemisi malzeme listesini gösterir.
SaladChef.cs:
namespace BlazorSample;
public class SaladChef
{
public string[] SaladToppers = { "Horva", "Kanda Root", "Krintar", "Plomeek",
"Syto Bean" };
}
Uygulamanın DI kapsayıcısında SaladChef dosyasında Program kaydedin.
builder.Services.AddTransient<SaladChef>();
IsValid Aşağıdaki SaladChefValidatorAttribute sınıfın yöntemi, kullanıcının girişini denetlemek için DI'den hizmeti alırSaladChef.
SaladChefValidatorAttribute.cs:
using System.ComponentModel.DataAnnotations;
namespace BlazorSample;
public class SaladChefValidatorAttribute : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value,
ValidationContext validationContext)
{
var saladChef = validationContext.GetRequiredService<SaladChef>();
if (saladChef.SaladToppers.Contains(value?.ToString()))
{
return ValidationResult.Success;
}
return new ValidationResult("Is that a Vulcan salad topper?! " +
"The following toppers are available for a Ten Forward salad: " +
string.Join(", ", saladChef.SaladToppers));
}
}
Aşağıdaki bileşen, salata bileşen dizesine SaladChefValidatorAttribute[SaladChefValidator](SaladIngredient ) uygulayarak kullanıcı girişini doğrular.
Starship12.razor:
@page "/starship-12"
@inject SaladChef SaladChef
<EditForm Model="this" autocomplete="off" FormName="Starship12">
<DataAnnotationsValidator />
<div>
<label>
Salad topper (@saladToppers):
<input @bind="SaladIngredient" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
<ul>
@foreach (var message in context.GetValidationMessages())
{
<li class="validation-message">@message</li>
}
</ul>
</EditForm>
@code {
private string? saladToppers;
[SaladChefValidator]
public string? SaladIngredient { get; set; }
protected override void OnInitialized() =>
saladToppers ??= string.Join(", ", SaladChef.SaladToppers);
}
@page "/starship-12"
@inject SaladChef SaladChef
<EditForm Model="this" autocomplete="off" FormName="Starship12">
<DataAnnotationsValidator />
<div>
<label>
Salad topper (@saladToppers):
<input @bind="SaladIngredient" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
<ul>
@foreach (var message in context.GetValidationMessages())
{
<li class="validation-message">@message</li>
}
</ul>
</EditForm>
@code {
private string? saladToppers;
[SaladChefValidator]
public string? SaladIngredient { get; set; }
protected override void OnInitialized() =>
saladToppers ??= string.Join(", ", SaladChef.SaladToppers);
}
@page "/starship-12"
@inject SaladChef SaladChef
<EditForm Model="this" autocomplete="off">
<DataAnnotationsValidator />
<p>
<label>
Salad topper (@saladToppers):
<input @bind="SaladIngredient" />
</label>
</p>
<button type="submit">Submit</button>
<ul>
@foreach (var message in context.GetValidationMessages())
{
<li class="validation-message">@message</li>
}
</ul>
</EditForm>
@code {
private string? saladToppers;
[SaladChefValidator]
public string? SaladIngredient { get; set; }
protected override void OnInitialized() =>
saladToppers ??= string.Join(", ", SaladChef.SaladToppers);
}
Özel doğrulama CSS sınıf öznitelikleri
Özel doğrulama CSS sınıfı öznitelikleri, Bootstrap gibi CSS çerçeveleriyle tümleştirme yaparken kullanışlıdır.
Özel doğrulama CSS sınıf özniteliklerini belirtmek için, özel doğrulama için CSS stilleri sağlayarak başlayın. Aşağıdaki örnekte geçerli (validField) ve geçersiz (invalidField) stiller belirtilmiştir.
Uygulamanın stil sayfasına aşağıdaki CSS sınıflarını ekleyin:
.validField {
border-color: lawngreen;
}
.invalidField {
background-color: tomato;
}
Alan doğrulama iletilerini kontrol eden ve uygun geçerli veya geçersiz stili uygulayan bir FieldCssClassProvider sınıf oluşturun.
CustomFieldClassProvider.cs:
using Microsoft.AspNetCore.Components.Forms;
public class CustomFieldClassProvider : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext,
in FieldIdentifier fieldIdentifier)
{
var isValid = editContext.IsValid(fieldIdentifier);
return isValid ? "validField" : "invalidField";
}
}
using Microsoft.AspNetCore.Components.Forms;
public class CustomFieldClassProvider : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext,
in FieldIdentifier fieldIdentifier)
{
var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
return isValid ? "validField" : "invalidField";
}
}
CustomFieldClassProvider sınıfını, formun EditContext örneğindeki Alan CSS Sınıf Sağlayıcısı olarak SetFieldCssClassProvider ile ayarlayın.
Starship13.razor:
@page "/starship-13"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship13> Logger
<EditForm EditContext="editContext" OnValidSubmit="Submit" FormName="Starship13">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
private EditContext? editContext;
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
editContext.SetFieldCssClassProvider(new CustomFieldClassProvider());
}
private void Submit() => Logger.LogInformation("Submit: Processing form");
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
@page "/starship-13"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship13> Logger
<EditForm EditContext="editContext" OnValidSubmit="Submit" FormName="Starship13">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit">Submit</button>
</div>
</EditForm>
@code {
private EditContext? editContext;
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
editContext.SetFieldCssClassProvider(new CustomFieldClassProvider());
}
private void Submit() => Logger.LogInformation("Submit: Processing form");
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
@page "/starship-13"
@using System.ComponentModel.DataAnnotations
@inject ILogger<Starship13> Logger
<EditForm EditContext="editContext" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText @bind-Value="Model!.Id" />
<button type="submit">Submit</button>
</EditForm>
@code {
private EditContext? editContext;
public Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??= new();
editContext = new(Model);
editContext.SetFieldCssClassProvider(new CustomFieldClassProvider());
}
private void Submit()
{
Logger.LogInformation("Submit called: Processing the form");
}
public class Starship
{
[Required]
[StringLength(10, ErrorMessage = "Id is too long.")]
public string? Id { get; set; }
}
}
Yukarıdaki örnek, tüm form alanlarının geçerliliğini denetler ve her alana bir stil uygular. Formun alanların yalnızca bir alt kümesine özel stiller uygulaması gerekiyorsa, CustomFieldClassProvider stilleri koşullu olarak uygulayın. Aşağıdaki CustomFieldClassProvider2 örnek, yalnızca Name alana bir stil uygular.
Name ile eşleşmeyen alanlar için string.Empty döndürülür ve stil uygulanmaz.
Yansıma kullanılarak, alan, HTML varlığına atanmaktan ziyade model üyesinin özelliği veya alan adıyla eşleştirilir.
CustomFieldClassProvider2.cs:
using Microsoft.AspNetCore.Components.Forms;
public class CustomFieldClassProvider2 : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext,
in FieldIdentifier fieldIdentifier)
{
if (fieldIdentifier.FieldName == "Name")
{
var isValid = editContext.IsValid(fieldIdentifier);
return isValid ? "validField" : "invalidField";
}
return string.Empty;
}
}
using Microsoft.AspNetCore.Components.Forms;
public class CustomFieldClassProvider2 : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext,
in FieldIdentifier fieldIdentifier)
{
if (fieldIdentifier.FieldName == "Name")
{
var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
return isValid ? "validField" : "invalidField";
}
return string.Empty;
}
}
Not
Önceki örnekte alan adıyla eşleştirme büyük/küçük harfe duyarlıdır, bu nedenle "Name" olarak belirlenmiş bir model özelliği üyesinin "Name" üzerindeki koşullu denetimle eşleşmesi gerekir:
-
Doğru eşleşmeler:
fieldId.FieldName == "Name" -
Eşleşmede başarısız:
fieldId.FieldName == "name" -
Eşleşmede başarısız:
fieldId.FieldName == "NAME" -
Eşleşmede başarısız:
fieldId.FieldName == "nAmE"
öğesine Modelek bir özellik ekleyin, örneğin:
[StringLength(10, ErrorMessage = "Description is too long.")]
public string? Description { get; set; }
Description öğesini CustomValidationForm bileşeninin formuna ekleyin.
<InputText @bind-Value="Model!.Description" />
Bileşenin EditContextOnInitialized yöntemindeki örneği yeni Alan CSS Sınıf Sağlayıcısını kullanacak şekilde güncelleştirin:
editContext?.SetFieldCssClassProvider(new CustomFieldClassProvider2());
CSS doğrulama sınıfı Description alanına uygulanmadığından, stil verilmemiş. Ancak, alan doğrulaması normal şekilde çalışır. 10'dan fazla karakter sağlanırsa doğrulama özeti şu hatayı gösterir:
Açıklama çok uzun.
Aşağıdaki örnekte:
Alana özel CSS stili uygulanır
Name.Diğer tüm alanlar, Blazor'nin varsayılan mantığına benzer bir mantık uygular ve Blazor'nin varsayılan alan CSS doğrulama stillerini
modifiedilevalidveyainvalidkullanır. Varsayılan stiller için, uygulama bir Blazor proje şablonunu temel alırsa bunları uygulamanın stil sayfasına eklemeniz gerekmediğini unutmayın. Proje şablonuna Blazor dayalı olmayan uygulamalar için, varsayılan stiller uygulamanın stil sayfasına eklenebilir:.valid.modified:not([type=checkbox]) { outline: 1px solid #26b050; } .invalid { outline: 1px solid red; }
CustomFieldClassProvider3.cs:
using Microsoft.AspNetCore.Components.Forms;
public class CustomFieldClassProvider3 : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext,
in FieldIdentifier fieldIdentifier)
{
var isValid = editContext.IsValid(fieldIdentifier);
if (fieldIdentifier.FieldName == "Name")
{
return isValid ? "validField" : "invalidField";
}
else
{
if (editContext.IsModified(fieldIdentifier))
{
return isValid ? "modified valid" : "modified invalid";
}
else
{
return isValid ? "valid" : "invalid";
}
}
}
}
using Microsoft.AspNetCore.Components.Forms;
public class CustomFieldClassProvider3 : FieldCssClassProvider
{
public override string GetFieldCssClass(EditContext editContext,
in FieldIdentifier fieldIdentifier)
{
var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
if (fieldIdentifier.FieldName == "Name")
{
return isValid ? "validField" : "invalidField";
}
else
{
if (editContext.IsModified(fieldIdentifier))
{
return isValid ? "modified valid" : "modified invalid";
}
else
{
return isValid ? "valid" : "invalid";
}
}
}
}
Bileşenin EditContext örneğini, OnInitialized yönteminde önceki Alan CSS Sınıf Sağlayıcısını kullanacak şekilde güncelleyin.
editContext.SetFieldCssClassProvider(new CustomFieldClassProvider3());
kullanarak CustomFieldClassProvider3:
- alanı,
Nameuygulamanın özel doğrulama CSS stillerini kullanır. - alanı,
Description'nin mantığına Blazorve Blazor'nin varsayılan alanı CSS doğrulama stillerine benzer bir mantık kullanır.
"IValidatableObject ile sınıf seviyesinde doğrulama"
Form modelleri için (API belgeleri) ile IValidatableObject sınıf düzeyinde doğrulama desteklenir.Blazor
IValidatableObject doğrulama yalnızca form gönderildiğinde ve yalnızca diğer tüm doğrulamalar başarılı olursa yürütülür.
Blazor veri açıklama notları doğrulama paketi
Not
PaketMicrosoft.AspNetCore.Components.DataAnnotations.Validation artık .NET 10 veya üzerini hedefleyen uygulamalar için önerilmez. Daha fazla bilgi için İç içe nesneler, koleksiyon türleri ve karmaşık türler bölümüne bakın.
Paket, Microsoft.AspNetCore.Components.DataAnnotations.Validation bileşeni kullanarak DataAnnotationsValidator doğrulama deneyimi boşluklarını doldurur. Paket şu anda deneyseldir.
Uyarı
Paket, Microsoft.AspNetCore.Components.DataAnnotations.ValidationNuGet.org sürüm adayının en son sürümüne sahiptir. Şu anda deneysel sürüm adayı paketini kullanmaya devam edin. Deneysel özellikler, özelliğin uygulanabilirliğini incelemek amacıyla kullanılır ve kararlı bir sürümde gönderilmeyebilir.
Daha fazla güncelleştirme için Duyurular GitHub deposunudotnet/aspnetcore, GitHub deposunu veya bu konu başlığını izleyin.
[CompareProperty] özniteliği
CompareAttribute, DataAnnotationsValidator bileşeniyle iyi çalışmaz çünkü DataAnnotationsValidator, doğrulama sonucunu belirli bir üyeyle ilişkilendirmez. Bu, alan düzeyi doğrulama ile bir gönderme sırasında modelin tamamı doğrulandığında arasında tutarsız davranışa neden olabilir.
Microsoft.AspNetCore.Components.DataAnnotations.Validation
paket, ComparePropertyAttributebu sınırlamaları geçici olarak karşılayan ek bir doğrulama özniteliği ekler. Bir Blazor uygulamasında, [CompareProperty] doğrudan [Compare] özniteliğinin yerine geçer.
İç içe nesneler ve koleksiyon türleri
Blazor form doğrulaması, yerleşik DataAnnotationsValidatorile iç içe nesnelerin ve koleksiyon öğelerinin özelliklerini doğrulama desteğini içerir.
Doğrulanmış bir form oluşturmak için, önceki gibi bir DataAnnotationsValidator bileşenin içinde bir EditForm bileşen kullanın.
İç içe nesneler ve koleksiyon türleri doğrulama özelliğini kabul etmek için:
-
AddValidation Hizmetlerin kaydedildiği dosyada
Programuzantı yöntemini çağırın. - Form modeli türlerini bir bileşende (Razor) değil
.razorC# sınıf dosyasında bildirin. - Kök form modeli türüne özniteliğiyle ek açıklama ekleyin
[ValidatableType].
Önceki adımları izlemeden, form doğrulama davranışı iç içe model ve koleksiyon türü doğrulamasını içermez.
Aşağıdaki örnek, geliştirilmiş form doğrulama ile müşteri siparişlerini gösterir (kısa süre için ayrıntılar atlanmıştır):
Program.cs'de, hizmet koleksiyonunu AddValidation ile çağırın.
builder.Services.AddValidation();
Aşağıdaki Order sınıfta, [ValidatableType] özniteliği en üst düzey model türünde gereklidir. Diğer türler otomatik olarak bulunur.
OrderItem ve ShippingAddress, özlülük adına gösterilmez, ancak iç içe ve koleksiyon doğrulaması, eğer gösterilselerdi, bu türlerde aynı şekilde çalışır.
Order.cs:
using System.ComponentModel.DataAnnotations;
[ValidatableType]
public class Order
{
public Customer Customer { get; set; } = new();
public List<OrderItem> OrderItems { get; set; } = [];
}
public class Customer
{
[Required(ErrorMessage = "Name is required.")]
public string? FullName { get; set; }
[Required(ErrorMessage = "Email is required.")]
public string? Email { get; set; }
public ShippingAddress ShippingAddress { get; set; } = new();
}
Aşağıdaki OrderPage bileşende DataAnnotationsValidator bileşeni, EditForm bileşeninde bulunur.
OrderPage.razor:
<EditForm Model="Model">
<DataAnnotationsValidator />
<h3>Customer Details</h3>
<div class="mb-3">
<label>
Full Name
<InputText @bind-Value="Model!.Customer.FullName" />
</label>
<ValidationMessage For="@(() => Model!.Customer.FullName)" />
</div>
// ... form continues ...
</EditForm>
@code {
public Order? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
}
Razor bileşenler dışında model türlerini bildirme gereksinimi, hem yeni doğrulama özelliği hem de derleyici .razor kaynak oluşturucu kullandığı için ortaya çıkmaktadır. Şu anda, bir kaynak oluşturucunun çıkışı başka bir kaynak oluşturucu için giriş olarak kullanılamaz.
Farklı bir derlemedeki doğrulama modellerini kullanma yönergeleri için Farklı bir derlemedeki doğrulama modellerini kullanma bölümüne bakın.
İç içe nesneler, koleksiyon türleri ve karmaşık türler
Not
.NET 10 veya üzerini hedefleyen uygulamalar için artık bu bölümde açıklanan Microsoft.AspNetCore.Components.DataAnnotations.Validation paketi ve yaklaşımı kullanmanızı önermeyiz. Bileşenin yerleşik doğrulama özelliklerini DataAnnotationsValidator kullanmanızı öneririz.
Blazor yerleşik DataAnnotationsValidatorile veri ek açıklamalarını kullanarak form girişini doğrulama desteği sağlar. Ancak , DataAnnotationsValidator .NET 9 veya önceki sürümlerinde yalnızca koleksiyon veya karmaşık tür özellikleri olmayan forma bağlı olan modelin üst düzey özellikleri doğrulanır.
İlişkili modelin koleksiyon ve karmaşık tür özellikleri de dahil olmak üzere nesne grafiğinin tamamını doğrulamak için deneysel ObjectGraphDataAnnotationsValidator .NET 9 veya önceki sürümlerde sağlanan öğesini kullanın:Microsoft.AspNetCore.Components.DataAnnotations.Validation
<EditForm ...>
<ObjectGraphDataAnnotationsValidator />
...
</EditForm>
ile [ValidateComplexType]model özelliklerine açıklama ekleyin. Aşağıdaki model sınıflarında, ShipDescription sınıfı model forma bağlandığında, doğrulama için ek veri açıklamalarını içerir.
Starship.cs:
using System;
using System.ComponentModel.DataAnnotations;
public class Starship
{
...
[ValidateComplexType]
public ShipDescription ShipDescription { get; set; } = new();
...
}
ShipDescription.cs:
using System;
using System.ComponentModel.DataAnnotations;
public class ShipDescription
{
[Required]
[StringLength(40, ErrorMessage = "Description too long (40 char).")]
public string? ShortDescription { get; set; }
[Required]
[StringLength(240, ErrorMessage = "Description too long (240 char).")]
public string? LongDescription { get; set; }
}
Farklı bir derlemeden doğrulama modelleri kullanma
Örneğin, bir kitaplık veya bir .Client'in Blazor Web App projesi gibi farklı bir derlemede tanımlanan model doğrulaması için:
- Kitaplık düz bir sınıf kitaplığıysa (ve
Microsoft.NET.Sdk.WebveyaMicrosoft.NET.Sdk.RazorSDK'larına dayanmıyorsa), NuGet paketi için kitaplığaMicrosoft.Extensions.Validationbir paket başvurusu ekleyin. Bu bölümün ilerleyen bölümlerinde açıklanan düz sınıf kitaplıkları için ek adımlar gereklidir. - Kitaplıkta veya
.Clientprojesinde IServiceCollection örneğini bağımsız değişken olarak alan ve bu örneği üzerinde AddValidation çağıran bir yöntem oluşturun. - Uygulamada hem yöntemi hem de AddValidation öğesini çağırın.
Yukarıdaki yaklaşım, her iki derlemeden türlerin doğrulanmasına neden olur.
Aşağıdaki örnekte, AddValidationForTypesInClient projesinde tanımlanan türler kullanılarak doğrulama amacıyla .Client projesinin Blazor Web App için .Client yöntemi oluşturulur.
ServiceCollectionExtensions.cs (.Client projesinde):
namespace BlazorSample.Client.Extensions;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddValidationForTypesInClient(
this IServiceCollection collection)
{
return collection.AddValidation();
}
}
Sunucu projesinin Program dosyasına namespace ekleyin ve .Client projesinin servis koleksiyonu genişletme metodunu (AddValidationForTypesInClient) çağırın AddValidation.
using BlazorSample.Client.Extensions;
...
builder.Services.AddValidationForTypesInClient();
builder.Services.AddValidation();
Paketin Microsoft.Extensions.Validation (ValidatableTypeAttribute ve SkipValidationAttribute) yeni öznitelikleri .NET 10'da deneysel olarak yayımlanır. Paket, çerçeveler arasında doğrulama özellikleri için yeni bir paylaşılan altyapı sağlamaya yöneliktir ve deneysel türleri yayımlamak, çerçeveleri kullanma konusunda daha iyi destek için genel API'nin son tasarımı için daha fazla esneklik sağlar.
Uygulamalarda Blazor türler, oluşturulan ekli öznitelik aracılığıyla kullanılabilir hale getirilir. SDK'yı Microsoft.NET.Sdk.Web<Project Sdk="Microsoft.NET.Sdk.Web"> kullanan bir web uygulaması projesi veya SDK'yı Microsoft.NET.Sdk.Razor<Project Sdk="Microsoft.NET.Sdk.Razor"> kullanan bir RCL Razor bileşenleri içeriyorsa .razor, çerçeve otomatik olarak proje içinde (Microsoft.Extensions.Validation.Embedded.ValidatableType, Microsoft.Extensions.Validation.Embedded.SkipValidation) bir iç öznitelik oluşturur. Bu türler gerçek özniteliklerle değiştirilebilir ve deneysel olarak işaretlenmez. Çoğu durumda geliştiriciler, sınıflarındaki öznitelikleri kaynaklarıyla ilgilenmeden kullanır [ValidatableType]/[SkipValidation] .
Ancak, önceki yaklaşım, Microsoft.NET.Sdk SDK'sını (<Project Sdk="Microsoft.NET.Sdk">) kullanan basit sınıf kitaplıklarında geçerli değildir. Türlerin düz sınıf kitaplığında kullanılması bir kod analizi uyarısına neden olur:
ASP0029: 'Microsoft.Extensions.Validation.ValidatableTypeAttribute' yalnızca değerlendirme amaçlıdır ve gelecekteki güncelleştirmelerde değiştirilebilir veya kaldırılabilir. Devam etmek için bu tanılamayı gizleme.
Uyarı, aşağıdaki yaklaşımlardan herhangi biri kullanılarak gizlenebilir:
<NoWarn>Proje dosyasındaki bir özellik:<PropertyGroup> <NoWarn>$(NoWarn);ASP0029</NoWarn> </PropertyGroup>pragmaÖzniteliğin kullanıldığı yönerge:#pragma warning disable ASP0029 [Microsoft.Extensions.Validation.ValidatableType] #pragma warning restore ASP0029EditorConfig dosyası (
.editorconfig) kuralı:dotnet_diagnostic.ASP0029.severity = none
Uyarıyı gizleme kabul edilemezse, Web ve Razor SDK'ların otomatik olarak oluşturduğu kitaplıkta katıştırılmış özniteliği el ile oluşturun.
ValidatableTypeAttribute.cs:
namespace Microsoft.Extensions.Validation.Embedded
{
[AttributeUsage(AttributeTargets.Class)]
internal sealed class ValidatableTypeAttribute : Attribute
{
}
}
Doğrulama kaynağı oluşturucusunun türü algılaması ve kullanması için tam ad alanını (Microsoft.Extensions.Validation.Embedded) ve sınıf adını (ValidatableTypeAttribute) kullanın. Genel bir using deyimi, ad alanı için ya global using Microsoft.Extensions.Validation.Embedded; deyimi ile ya da kitaplığın proje dosyasındaki <Using Include="Microsoft.Extensions.Validation.Embedded" /> öğesi ile bildirebilirsiniz.
Hangi yaklaşım benimsense, kodunuz için gelecekteki bir güncelleştirme için geçici çözümün mevcut olduğunu belirtir. .NET 11 (Kasım 2026) için düz sınıf kitaplıklarında doğrulama türlerinin benimsenmesini kolaylaştıran çerçeve güncelleştirmeleri planlanmaktadır.
Form doğrulamaya göre gönder düğmesini etkinleştirme
Form doğrulamaya göre gönder düğmesini etkinleştirmek ve devre dışı bırakmak için aşağıdaki örnek:
- Giriş bileşenleri makalesinin Örnek form
Starfleet Starship DatabaseöncekiStarship3formunun (bileşen) kısaltılmış bir sürümünü kullanır ve bu sürüm yalnızca geminin kimliği için bir değer kabul eder. Türün bir örneğiStarshipoluşturulduğunda diğerStarshipözellikler geçerli varsayılan değerler alır. - Bileşen başlatıldığında modeli atamak için formun EditContext kullanır.
- Gönder düğmesini etkinleştirmek ve devre dışı bırakmak için bağlamın OnFieldChanged geri çağırmasında formu doğrular.
-
IDisposable uygular ve
Disposeyönteminde olay işleyicisinin aboneliğini iptal eder. Daha fazla bilgi için bkz. ASP.NET Core Razor bileşen imhası.
Not
EditForm.EditContext öğesine atama yaparken, EditForm.Model öğesini EditForm öğesine de atamayın.
Starship14.razor:
@page "/starship-14"
@implements IDisposable
@inject ILogger<Starship14> Logger
<EditForm EditContext="editContext" OnValidSubmit="Submit" FormName="Starship14">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit" disabled="@formInvalid">Submit</button>
</div>
</EditForm>
@code {
private bool formInvalid = false;
private EditContext? editContext;
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??=
new()
{
Id = "NCC-1701",
Classification = "Exploration",
MaximumAccommodation = 150,
IsValidatedDesign = true,
ProductionDate = new DateTime(2245, 4, 11)
};
editContext = new(Model);
editContext.OnFieldChanged += HandleFieldChanged;
}
private void HandleFieldChanged(object? sender, FieldChangedEventArgs e)
{
if (editContext is not null)
{
formInvalid = !editContext.Validate();
StateHasChanged();
}
}
private void Submit() => Logger.LogInformation("Submit: Processing form");
public void Dispose()
{
if (editContext is not null)
{
editContext.OnFieldChanged -= HandleFieldChanged;
}
}
}
@page "/starship-14"
@implements IDisposable
@inject ILogger<Starship14> Logger
<EditForm EditContext="editContext" OnValidSubmit="Submit" FormName="Starship14">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit" disabled="@formInvalid">Submit</button>
</div>
</EditForm>
@code {
private bool formInvalid = false;
private EditContext? editContext;
[SupplyParameterFromForm]
private Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??=
new()
{
Id = "NCC-1701",
Classification = "Exploration",
MaximumAccommodation = 150,
IsValidatedDesign = true,
ProductionDate = new DateTime(2245, 4, 11)
};
editContext = new(Model);
editContext.OnFieldChanged += HandleFieldChanged;
}
private void HandleFieldChanged(object? sender, FieldChangedEventArgs e)
{
if (editContext is not null)
{
formInvalid = !editContext.Validate();
StateHasChanged();
}
}
private void Submit() => Logger.LogInformation("Submit: Processing form");
public void Dispose()
{
if (editContext is not null)
{
editContext.OnFieldChanged -= HandleFieldChanged;
}
}
}
@page "/starship-14"
@implements IDisposable
@inject ILogger<Starship14> Logger
<EditForm EditContext="editContext" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<ValidationSummary />
<div>
<label>
Identifier:
<InputText @bind-Value="Model!.Id" />
</label>
</div>
<div>
<button type="submit" disabled="@formInvalid">Submit</button>
</div>
</EditForm>
@code {
private bool formInvalid = false;
private EditContext? editContext;
private Starship? Model { get; set; }
protected override void OnInitialized()
{
Model ??=
new()
{
Id = "NCC-1701",
Classification = "Exploration",
MaximumAccommodation = 150,
IsValidatedDesign = true,
ProductionDate = new DateTime(2245, 4, 11)
};
editContext = new(Model);
editContext.OnFieldChanged += HandleFieldChanged;
}
private void HandleFieldChanged(object? sender, FieldChangedEventArgs e)
{
if (editContext is not null)
{
formInvalid = !editContext.Validate();
StateHasChanged();
}
}
private void Submit()
{
Logger.LogInformation("Submit called: Processing the form");
}
public void Dispose()
{
if (editContext is not null)
{
editContext.OnFieldChanged -= HandleFieldChanged;
}
}
}
Form geçerli değerlerle önceden yüklenmemişse ve form yüklenirken Submit düğmesini devre dışı bırakmak istiyorsanız, formInvalid öğesini true olarak ayarlayın.
Önceki yaklaşımın bir yan etkisi, kullanıcı herhangi bir alanla etkileşime geçtikten sonra bir doğrulama özetinin (ValidationSummary bileşen) geçersiz alanlarla doldurulmadır. Bu senaryoyu aşağıdaki yollardan biriyle ele alın:
- Formda bileşen ValidationSummary kullanmayın.
-
ValidationSummary Gönder düğmesi seçildiğinde bileşeni görünür hale getirin (örneğin, bir
Submityöntemde).
<EditForm ... EditContext="editContext" OnValidSubmit="Submit" ...>
<DataAnnotationsValidator />
<ValidationSummary style="@displaySummary" />
...
<button type="submit" disabled="@formInvalid">Submit</button>
</EditForm>
@code {
private string displaySummary = "display:none";
...
private void Submit()
{
displaySummary = "display:block";
}
}
DataAnnotationsValidator doğrulama davranışı
Bileşen, DataAnnotationsValidator ile aynı doğrulama sırasına ve kısa devre davranışına System.ComponentModel.DataAnnotations.Validatorsahiptir. Türün Tbir örneği doğrulanırken aşağıdaki kurallar uygulanır:
- öğesinin
Tüye özellikleri, iç içe nesneleri yinelemeli olarak doğrulama da dahil olmak üzere doğrulanır. - türü düzeyinde öznitelikler
Tdoğrulanır. -
IValidatableObject.Validate yöntemi uygulanırsa
Tyürütülür.
Yukarıdaki adımlardan biri doğrulama hatası oluşturursa, kalan adımlar atlanır.
ASP.NET Core