ASP.NET Core MVC ve Razor Sayfalarda model doğrulama

Bu makalede, ASP.NET Core MVC veya Razor Pages uygulamasında kullanıcı girişinin nasıl doğrulanması açıklanır.

Örnek kodu görüntüleme veya indirme (indirme).

Model durumu

Model durumu, iki alt sistemden gelen hataları temsil eder: model bağlama ve model doğrulama. Model bağlamasından kaynaklanan hatalar genellikle veri dönüştürme hatalarıdır. Örneğin, bir tamsayı alanına "x" girilir. Model doğrulama, model bağlamadan sonra gerçekleşir ve verilerin iş kurallarına uymadığı hataları bildirir. Örneğin, derecelendirmenin 1 ile 5 arasında olmasını bekleyen bir alana 0 girilir.

Hem model bağlama hem de model doğrulama, bir denetleyici eyleminin veya Razor Pages işleyici yönteminin yürütülmesinden önce gerçekleşir. Web uygulamaları için uygun şekilde incelemek ModelState.IsValid ve tepki vermek uygulamanın sorumluluğundadır. Web uygulamaları genellikle aşağıdaki Razor Sayfalar örneğinde gösterildiği gibi sayfayı bir hata iletisiyle yeniden görüntüler:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movies.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Denetleyiciler ve görünümler içeren ASP.NET Core MVC için, aşağıdaki örnekte bir denetleyici eyleminin içinde nasıl denetlenecek ModelState.IsValid gösterilmektedir:

public async Task<IActionResult> Create(Movie movie)
{
    if (!ModelState.IsValid)
    {
        return View(movie);
    }

    _context.Movies.Add(movie);
    await _context.SaveChangesAsync();

    return RedirectToAction(nameof(Index));
}

Web API denetleyicilerinin [ApiController] özniteliğine sahip olup olmadığını denetlemeleri ModelState.IsValid gerekmez. Bu durumda, model durumu geçersiz olduğunda hata ayrıntılarını içeren otomatik bir HTTP 400 yanıtı döndürülür. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

Doğrulamayı yeniden çalıştırma

Doğrulama otomatiktir, ancak el ile yinelemek isteyebilirsiniz. Örneğin, bir özellik için bir değer hesaplayabilirsiniz ve özelliği hesaplanan değere ayarladıktan sonra doğrulamayı yeniden çalıştırmak isteyebilirsiniz. Doğrulamayı yeniden çalıştırmak için, doğrulanan modele özgü doğrulamayı temizlemek için öğesini ve ardından TryValidateModelöğesini çağırınModelStateDictionary.ClearValidationState:

public async Task<IActionResult> OnPostTryValidateAsync()
{
    var modifiedReleaseDate = DateTime.Now.Date;
    Movie.ReleaseDate = modifiedReleaseDate;

    ModelState.ClearValidationState(nameof(Movie));
    if (!TryValidateModel(Movie, nameof(Movie)))
    {
        return Page();
    }

    _context.Movies.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Doğrulama öznitelikleri

Doğrulama öznitelikleri, model özellikleri için doğrulama kuralları belirtmenize olanak sağlar. Örnek uygulamadan alınan aşağıdaki örnekte, doğrulama öznitelikleriyle açıklama eklenen bir model sınıfı gösterilmektedir. [ClassicMovie] özniteliği özel bir doğrulama özniteliğidir ve diğerleri yerleşiktir. gösterilmez, [ClassicMovieWithClientValidator]bu da özel bir öznitelik uygulamak için alternatif bir yol gösterir.

public class Movie
{
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; } = null!;

    [ClassicMovie(1960)]
    [DataType(DataType.Date)]
    [Display(Name = "Release Date")]
    public DateTime ReleaseDate { get; set; }

    [Required]
    [StringLength(1000)]
    public string Description { get; set; } = null!;

    [Range(0, 999.99)]
    public decimal Price { get; set; }

    public Genre Genre { get; set; }

    public bool Preorder { get; set; }
}

Yerleşik öznitelikler

Yerleşik doğrulama özniteliklerinden bazıları şunlardır:

  • [ValidateNever]: Bir özelliğin veya parametrenin doğrulamanın dışında tutulması gerektiğini gösterir.
  • [CreditCard]: Özelliğin kredi kartı biçiminde olduğunu doğrular. jQuery Doğrulama Ek Yöntemleri gerektirir.
  • [Karşılaştır]: Modeldeki iki özelliğin eşleştiklerini doğrular.
  • [EmailAddress]: Özelliğin e-posta biçimi olduğunu doğrular.
  • [Telefon]: Özelliğin telefon numarası biçimine sahip olduğunu doğrular.
  • [Aralık]: Özellik değerinin belirtilen aralık içinde olduğunu doğrular.
  • [RegularExpression]: Özellik değerinin belirtilen normal ifadeyle eşleştiklerini doğrular.
  • [Gerekli]: Alanın null olmadığını doğrular. Bu özniteliğin davranışıyla ilgili ayrıntılar için bkz [Required] . öznitelik .
  • [StringLength]: Dize özellik değerinin belirtilen uzunluk sınırını aşmadığını doğrular.
  • [Url]: Özelliğin BIR URL biçimi olduğunu doğrular.
  • [Uzak]: Sunucuda bir eylem yöntemi çağırarak istemcideki girişi doğrular. Bu özniteliğin davranışıyla ilgili ayrıntılar için bkz [Remote] . öznitelik .

Doğrulama özniteliklerinin tam listesi ad alanında System.ComponentModel.DataAnnotations bulunabilir.

Hata iletileri

Doğrulama öznitelikleri, geçersiz giriş için görüntülenecek hata iletisini belirtmenize olanak sağlar. Örneğin:

[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]

Öznitelikler dahili olarak, alan adı ve bazen ek yer tutucular için bir yer tutucu ile çağrır String.Format . Örneğin:

[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]

Bir Name özelliğe uygulandığında, önceki kod tarafından oluşturulan hata iletisi "Ad uzunluğu 6 ile 8 arasında olmalıdır".

Belirli bir özniteliğin hata iletisi için hangi parametrelerin geçirildiğini String.Format öğrenmek için Bkz . DataAnnotations kaynak kodu.

Doğrulama hatalarında JSON özellik adlarını kullanma

Varsayılan olarak, bir doğrulama hatası oluştuğunda model doğrulaması, hata anahtarı olarak özellik adıyla bir ModelStateDictionary oluşturur. Tek sayfalı uygulamalar gibi bazı uygulamalar, Web API'lerinden oluşturulan doğrulama hataları için JSON özellik adlarının kullanılmasından yararlanmaktadır. Aşağıdaki kod, JSON özellik adlarını kullanmak için öğesini kullanacak SystemTextJsonValidationMetadataProvider şekilde doğrulamayı yapılandırmaktadır:

using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new SystemTextJsonValidationMetadataProvider());
});

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Aşağıdaki kod, Json.NET kullanırken NewtonsoftJsonValidationMetadataProvider JSON özellik adını kullanmak için doğrulamayı yapılandırmaktadır:

using Microsoft.AspNetCore.Mvc.NewtonsoftJson;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers(options =>
{
    options.ModelMetadataDetailsProviders.Add(new NewtonsoftJsonValidationMetadataProvider());
}).AddNewtonsoftJson();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Camel-casing kullanma ilkesi örneği için GitHub'da bölümüne bakınProgram.cs.

Null değer atanamayan başvuru türleri ve [Gerekli] özniteliği

Doğrulama sistemi, null değer atanamayan parametreleri veya ilişkili özellikleri bir [Required(AllowEmptyStrings = true)] özniteliği varmış gibi ele alır. MVC, bağlamları etkinleştirerek Nullable , boş değer atanamayan özellikleri veya parametreleri özniteliğiyle ilişkilendirilmiş gibi örtük olarak doğrulamaya [Required(AllowEmptyStrings = true)] başlar. Aşağıdaki kodu inceleyin:

public class Person
{
    public string Name { get; set; }
}

Uygulama ile <Nullable>enable</Nullable>oluşturulduysa, JSON veya form gönderisinde için Name eksik bir değer doğrulama hatasıyla sonuçlanır. Öznitelik örtülü olduğundan [Required(AllowEmptyStrings = true)] bu çelişkili görünebilir, ancak boş dizeler varsayılan olarak null değerine dönüştürüldüğünden bu beklenen bir davranıştır. Özelliği için null veya eksik değerlerin belirtilmesine izin vermek için Name null atanabilir bir başvuru türü kullanın:

public class Person
{
    public string? Name { get; set; }
}

Bu davranış, içinde Program.csyapılandırılarak SuppressImplicitRequiredAttributeForNonNullableReferenceTypes devre dışı bırakılabilir:

builder.Services.AddControllers(
    options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);

Sunucuda [Gerekli] doğrulama

Sunucuda, özellik null olduğunda gerekli bir değerin eksik olduğu kabul edilir. Null değer atanamayan bir alan her zaman geçerlidir ve özniteliğin [Required] hata iletisi hiçbir zaman görüntülenmez.

Ancak, null değer atanamayan bir özellik için model bağlama başarısız olabilir ve gibi The value '' is invalidbir hata iletisiyle sonuçlanabilir. Null değer atanamayan türlerin sunucu tarafı doğrulaması için özel bir hata iletisi belirtmek için aşağıdaki seçeneklere sahipsiniz:

  • Alanı null atanabilir hale getirin (örneğin, decimal? yerine decimal). Null atanabilir<T> değer türleri standart null atanabilir türler olarak kabul edilir.

  • Aşağıdaki örnekte gösterildiği gibi model bağlaması tarafından kullanılacak varsayılan hata iletisini belirtin:

    builder.Services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.MaxModelValidationErrors = 50;
            options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
                _ => "The field is required.");
        });
    
    builder.Services.AddSingleton
        <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
    

    Varsayılan iletileri ayarlayabileceğiniz model bağlama hataları hakkında daha fazla bilgi için bkz DefaultModelBindingMessageProvider. .

İstemcide [Gerekli] doğrulama

Null değer atanamayan türler ve dizeler istemcide sunucuyla karşılaştırıldığında farklı şekilde işlenir. İstemcide:

  • Bir değerin mevcut olduğu kabul edilir, ancak bu değer için giriş girilirse. Bu nedenle, istemci tarafı doğrulama null atanamayan türleri null atanabilir türlerle aynı şekilde işler.
  • Dize alanındaki boşluk, jQuery Doğrulaması gerekli yöntemi tarafından geçerli giriş olarak kabul edilir. Sunucu tarafı doğrulaması, yalnızca boşluk girilirse gerekli dize alanını geçersiz sayıyor.

Daha önce belirtildiği gibi, null atanamayan türler bir [Required(AllowEmptyStrings = true)] özniteliği varmış gibi kabul edilir. Bu, özniteliğini uygulamasanız bile istemci tarafı doğrulamasını [Required(AllowEmptyStrings = true)] alabileceğiniz anlamına gelir. Ancak özniteliğini kullanmazsanız varsayılan bir hata iletisi alırsınız. Özel bir hata iletisi belirtmek için özniteliğini kullanın.

[Remote] özniteliği

[Remote] özniteliği, alan girişinin geçerli olup olmadığını belirlemek için sunucuda bir yöntem çağırmayı gerektiren istemci tarafı doğrulaması uygular. Örneğin, uygulamanın bir kullanıcı adının zaten kullanımda olup olmadığını doğrulaması gerekebilir.

Uzaktan doğrulama uygulamak için:

  1. JavaScript'in çağıracağı bir eylem yöntemi oluşturun. jQuery Doğrulama uzak yöntemi bir JSON yanıtı bekler:

    • true giriş verilerinin geçerli olduğu anlamına gelir.
    • false, undefinedveya null girişin geçersiz olduğu anlamına gelir. Varsayılan hata iletisini görüntüleyin.
    • Diğer dizeler girişin geçersiz olduğu anlamına gelir. Dizeyi özel bir hata iletisi olarak görüntüleyin.

    Aşağıda özel hata iletisi döndüren bir eylem yöntemi örneği verilmiştir:

    [AcceptVerbs("GET", "POST")]
    public IActionResult VerifyEmail(string email)
    {
        if (!_userService.VerifyEmail(email))
        {
            return Json($"Email {email} is already in use.");
        }
    
        return Json(true);
    }
    
  2. Model sınıfında, aşağıdaki örnekte gösterildiği gibi doğrulama eylemi yöntemine işaret eden bir [Remote] öznitelikle özelliğine açıklama ekleyin:

    [Remote(action: "VerifyEmail", controller: "Users")]
    public string Email { get; set; } = null!;
    

JavaScript'i devre dışı bırakmış istemciler için de sunucu tarafı doğrulamasının uygulanması gerekir.

Ek alanlar

AdditionalFields özniteliğinin [Remote] özelliği, sunucudaki verilerde alan birleşimlerini doğrulamanıza olanak tanır. Örneğin, modelde User FirstName ve LastName özellikleri varsa, mevcut kullanıcıların bu ad çiftine sahip olmadığını doğrulamak isteyebilirsiniz. Aşağıdaki örnekte nasıl kullanılacağı gösterilmektedir AdditionalFields:

[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(LastName))]
[Display(Name = "First Name")]
public string FirstName { get; set; } = null!;

[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(FirstName))]
[Display(Name = "Last Name")]
public string LastName { get; set; } = null!;

AdditionalFieldsaçıkça "FirstName" ve "LastName" dizelerine ayarlanabilir, ancak nameof işlecinin kullanılması daha sonra yeniden düzenlemeyi kolaylaştırır. Bu doğrulama için eylem yöntemi hem hem de firstName lastName bağımsız değişkenlerini kabul etmelidir:

[AcceptVerbs("GET", "POST")]
public IActionResult VerifyName(string firstName, string lastName)
{
    if (!_userService.VerifyName(firstName, lastName))
    {
        return Json($"A user named {firstName} {lastName} already exists.");
    }

    return Json(true);
}

Kullanıcı bir ad veya soyadı girdiğinde, JavaScript bu ad çiftinin alınıp alınmadığını görmek için uzak bir çağrı yapar.

İki veya daha fazla ek alanı doğrulamak için, bunları virgülle ayrılmış liste olarak sağlayın. Örneğin, modele özellik MiddleName eklemek için özniteliğini [Remote] aşağıdaki örnekte gösterildiği gibi ayarlayın:

[Remote(action: "VerifyName", controller: "Users",
    AdditionalFields = nameof(FirstName) + "," + nameof(LastName))]
public string MiddleName { get; set; }

AdditionalFields, tüm öznitelik bağımsız değişkenleri gibi sabit bir ifade olmalıdır. Bu nedenle, başlatmak AdditionalFieldsiçin ilişkilendirilmiş bir dize veya çağrı Join kullanmayın.

Yerleşik özniteliklere alternatifler

Yerleşik öznitelikler tarafından sağlanmayan doğrulamaya ihtiyacınız varsa şunları yapabilirsiniz:

Özel öznitelikler

Yerleşik doğrulama özniteliklerinin işlemediğini senaryolar için özel doğrulama öznitelikleri oluşturabilirsiniz. öğesinden ValidationAttributedevralan bir sınıf oluşturun ve yöntemini geçersiz kılın IsValid .

IsValid yöntemi, doğrulanacak giriş olan value adlı bir nesneyi kabul eder. Aşırı yükleme, model bağlaması tarafından oluşturulan model örneği gibi ek bilgiler sağlayan bir ValidationContext nesneyi de kabul eder.

Aşağıdaki örnek, Klasik tarzdaki bir filmin yayın tarihinin belirtilen yıldan sonra olmadığını doğrular. Özniteliği [ClassicMovie] :

  • Yalnızca sunucuda çalıştırılır.
  • Klasik filmler için yayın tarihini doğrular:
public class ClassicMovieAttribute : ValidationAttribute
{
    public ClassicMovieAttribute(int year)
        => Year = year;

    public int Year { get; }

    public string GetErrorMessage() =>
        $"Classic movies must have a release year no later than {Year}.";

    protected override ValidationResult? IsValid(
        object? value, ValidationContext validationContext)
    {
        var movie = (Movie)validationContext.ObjectInstance;
        var releaseYear = ((DateTime)value!).Year;

        if (movie.Genre == Genre.Classic && releaseYear > Year)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }
}

movie Yukarıdaki örnekteki değişken, form gönderimindeki verileri içeren bir Movie nesneyi temsil eder. Doğrulama başarısız olduğunda, ValidationResult hata iletisi içeren bir döndürülür.

IValidatableObject

Yukarıdaki örnek yalnızca türlerle Movie çalışır. Sınıf düzeyi doğrulama için bir diğer seçenek de aşağıdaki örnekte gösterildiği gibi model sınıfında uygulamaktır IValidatableObject :

public class ValidatableMovie : IValidatableObject
{
    private const int _classicYear = 1960;

    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; } = null!;

    [DataType(DataType.Date)]
    [Display(Name = "Release Date")]
    public DateTime ReleaseDate { get; set; }

    [Required]
    [StringLength(1000)]
    public string Description { get; set; } = null!;

    [Range(0, 999.99)]
    public decimal Price { get; set; }

    public Genre Genre { get; set; }

    public bool Preorder { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Genre == Genre.Classic && ReleaseDate.Year > _classicYear)
        {
            yield return new ValidationResult(
                $"Classic movies must have a release year no later than {_classicYear}.",
                new[] { nameof(ReleaseDate) });
        }
    }
}

Özel doğrulama

Aşağıdaki kod, modeli inceledikten sonra bir model hatasının nasıl ekleneceğini gösterir:

if (Contact.Name == Contact.ShortName)
{
    ModelState.AddModelError("Contact.ShortName", 
                             "Short name can't be the same as Name.");
}

Aşağıdaki kod bir denetleyicide doğrulama testini uygular:

if (contact.Name == contact.ShortName)
{
    ModelState.AddModelError(nameof(contact.ShortName),
                             "Short name can't be the same as Name.");
}

Aşağıdaki kod, telefon numarasının ve e-postanın benzersiz olduğunu doğrular:

public async Task<IActionResult> OnPostAsync()
{
    // Attach Validation Error Message to the Model on validation failure.          

    if (Contact.Name == Contact.ShortName)
    {
        ModelState.AddModelError("Contact.ShortName", 
                                 "Short name can't be the same as Name.");
    }

    if (_context.Contact.Any(i => i.PhoneNumber == Contact.PhoneNumber))
    {
        ModelState.AddModelError("Contact.PhoneNumber",
                                  "The Phone number is already in use.");
    }
    if (_context.Contact.Any(i => i.Email == Contact.Email))
    {
        ModelState.AddModelError("Contact.Email", "The Email is already in use.");
    }

    if (!ModelState.IsValid || _context.Contact == null || Contact == null)
    {
        // if model is invalid, return the page with the model state errors.
        return Page();
    }
    _context.Contact.Add(Contact);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Aşağıdaki kod bir denetleyicide doğrulama testini uygular:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,ShortName,Email,PhoneNumber")] Contact contact)
{
    // Attach Validation Error Message to the Model on validation failure.
    if (contact.Name == contact.ShortName)
    {
        ModelState.AddModelError(nameof(contact.ShortName),
                                 "Short name can't be the same as Name.");
    }

    if (_context.Contact.Any(i => i.PhoneNumber == contact.PhoneNumber))
    {
        ModelState.AddModelError(nameof(contact.PhoneNumber),
                                  "The Phone number is already in use.");
    }
    if (_context.Contact.Any(i => i.Email == contact.Email))
    {
        ModelState.AddModelError(nameof(contact.Email), "The Email is already in use.");
    }

    if (ModelState.IsValid)
    {
        _context.Add(contact);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(contact);
}

Benzersiz bir telefon numarasını veya e-postayı denetlemek genellikle uzaktan doğrulama ile de yapılır.

ValidationResult

Aşağıdaki özel ValidateNameAttributedurumu göz önünde bulundurun:

public class ValidateNameAttribute : ValidationAttribute
{
    public ValidateNameAttribute()
    {
        const string defaultErrorMessage = "Error with Name";
        ErrorMessage ??= defaultErrorMessage;
    }

    protected override ValidationResult? IsValid(object? value,
                                         ValidationContext validationContext)
    {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
        {
            return new ValidationResult("Name is required.");
        }

        if (value.ToString()!.ToLower().Contains("zz"))
        {

            return new ValidationResult(
                        FormatErrorMessage(validationContext.DisplayName));
        }

        return ValidationResult.Success;
    }
}

Aşağıdaki kodda özel [ValidateName] öznitelik uygulanır:

public class Contact
{
    public Guid Id { get; set; }

    [ValidateName(ErrorMessage = "Name must not contain `zz`")] 
    public string? Name { get; set; }
    public string? Email { get; set; }
    public string? PhoneNumber { get; set; }
}

Model içerdiğinde zzyeni ValidationResult bir döndürülür.

Üst düzey düğüm doğrulama

En üst düzey düğümler şunlardır:

  • İşlem parametreleri
  • Denetleyici özellikleri
  • Sayfa işleyicisi parametreleri
  • Sayfa modeli özellikleri

Modele bağlı üst düzey düğümler, model özelliklerini doğrulamaya ek olarak doğrulanır. Örnek uygulamadan aşağıdaki örnekte yöntemi, VerifyPhone eylem parametresini doğrulamak phone için öğesini RegularExpressionAttribute kullanır:

[AcceptVerbs("GET", "POST")]
public IActionResult VerifyPhone(
    [RegularExpression(@"^\d{3}-\d{3}-\d{4}$")] string phone)
{
    if (!ModelState.IsValid)
    {
        return Json($"Phone {phone} has an invalid format. Format: ###-###-####");
    }

    return Json(true);
}

Üst düzey düğümler doğrulama öznitelikleriyle kullanabilir BindRequiredAttribute . Örnek uygulamadan alınan aşağıdaki örnekte yöntemi, CheckAge form gönderildiğinde parametrenin age sorgu dizesinden bağlanması gerektiğini belirtir:

[HttpPost]
public IActionResult CheckAge([BindRequired, FromQuery] int age)
{

Yaşı Denetle sayfasında ()CheckAge.cshtml iki form vardır. İlk form değerini Age 99 sorgu dizesi parametresi olarak gönderir: https://localhost:5001/Users/CheckAge?Age=99.

Sorgu dizesinden düzgün biçimlendirilmiş age bir parametre gönderildiğinde, form doğrulanır.

Yaşı Denetle sayfasındaki ikinci form, isteğin Age gövdesindeki değeri gönderir ve doğrulama başarısız olur. Parametrenin bir sorgu dizesinden gelmesi gerektiğinden age bağlama başarısız oluyor.

En fazla hata sayısı

Maksimum hata sayısına (varsayılan olarak 200) ulaşıldığında doğrulama durdurulur. Bu sayıyı içinde Program.csaşağıdaki kodla yapılandırabilirsiniz:

builder.Services.AddRazorPages()
    .AddMvcOptions(options =>
    {
        options.MaxModelValidationErrors = 50;
        options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
            _ => "The field is required.");
    });

builder.Services.AddSingleton
    <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();

En fazla özyineleme

ValidationVisitor doğrulanan modelin nesne grafını gezer. Derin veya sonsuz özyinelemeli modeller için doğrulama, yığın taşmasına neden olabilir. MvcOptions.MaxValidationDepth , ziyaretçi özyinelemesi yapılandırılmış bir derinliği aşarsa doğrulamayı erken durdurmanın bir yolunu sağlar. varsayılan değeri MvcOptions.MaxValidationDepth 32'dir.

Otomatik kısa devre

Model grafı doğrulama gerektirmiyorsa doğrulama otomatik olarak kısa devreli (atlanır) olur. Çalışma zamanının doğrulamayı atlayan nesneleri, temel öğe koleksiyonlarını (, byte[]string[], Dictionary<string, string>gibi) ve herhangi bir doğrulayıcı içermeyen karmaşık nesne graflarını içerir.

İstemci tarafı doğrulama

İstemci tarafı doğrulama, form geçerli olana kadar gönderimi engeller. Gönder düğmesi formu gönderen veya hata iletileri görüntüleyen JavaScript'i çalıştırır.

İstemci tarafı doğrulama, formda giriş hataları olduğunda sunucuya gereksiz bir gidiş dönüşten kaçınıyor. aşağıdaki betik başvuruları ve _Layout.cshtml _ValidationScriptsPartial.cshtml istemci tarafı doğrulamasını destekler:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.js"></script>

jQuery Göze Çarpmayan Doğrulama betiği, popüler jQuery Doğrulama eklentisini kullanan özel bir Microsoft ön uç kitaplığıdır. jQuery Göze Çarpmayan Doğrulama olmadan aynı doğrulama mantığını iki yerde kodlasanız: model özelliklerindeki sunucu tarafı doğrulama özniteliklerine ve ardından istemci tarafı betiklerine bir kez daha. Bunun yerine, Etiket Yardımcıları ve HTML yardımcıları doğrulama gerektiren form öğeleri için HTML 5 data- özniteliklerini işlemek üzere doğrulama özniteliklerini kullanır ve model özelliklerinden meta verileri yazar. jQuery Göze Çarpmayan Doğrulama, öznitelikleri ayrıştırarak data- mantığı jQuery Doğrulaması'na geçirir ve sunucu tarafı doğrulama mantığını istemciye etkili bir şekilde "kopyalar". Burada gösterildiği gibi etiket yardımcılarını kullanarak istemcide doğrulama hataları görüntüleyebilirsiniz:

<div class="form-group">
    <label asp-for="Movie.ReleaseDate" class="control-label"></label>
    <input asp-for="Movie.ReleaseDate" class="form-control" />
    <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
</div>

Yukarıdaki etiket yardımcıları aşağıdaki HTML'yi işler:

<div class="form-group">
    <label class="control-label" for="Movie_ReleaseDate">Release Date</label>
    <input class="form-control" type="date" data-val="true"
        data-val-required="The Release Date field is required."
        id="Movie_ReleaseDate" name="Movie.ReleaseDate" value="">
    <span class="text-danger field-validation-valid"
        data-valmsg-for="Movie.ReleaseDate" data-valmsg-replace="true"></span>
</div>

HTML çıkışındaki data- özniteliklerin özelliği için doğrulama özniteliklerine Movie.ReleaseDate karşılık geldiğini fark edin. Özniteliği, data-val-required kullanıcı yayın tarihi alanını doldurmazsa görüntülenecek bir hata iletisi içerir. jQuery Göze Çarpmayan Doğrulama bu değeri jQuery Validation required() yöntemine geçirir ve bu yöntem bu iletiyi eşlik eden <span> öğesinde görüntüler.

Veri türü doğrulaması, [DataType] özniteliği tarafından geçersiz kılınmadığı sürece bir özelliğin .NET türünü temel alır. Tarayıcıların kendi varsayılan hata iletileri vardır, ancak jQuery Doğrulama Engelleyici Olmayan Doğrulama paketi bu iletileri geçersiz kılabilir. [DataType]öznitelikleri ve [EmailAddress] gibi alt sınıflar hata iletisini belirtmenize olanak sağlar.

Göze çarpmayan doğrulama

Engelleyici olmayan doğrulama hakkında bilgi için bu GitHub sorununa bakın.

Dinamik Formlara Doğrulama Ekleme

jQuery Göze Çarpmayan Doğrulama, sayfa ilk yüklendiğinde doğrulama mantığını ve parametrelerini jQuery Doğrulaması'na geçirir. Bu nedenle doğrulama, dinamik olarak oluşturulan formlarda otomatik olarak çalışmaz. Doğrulamayı etkinleştirmek için jQuery Engelleyici Olmayan Doğrulama'ya dinamik formu oluşturduktan hemen sonra ayrıştırmasını söyleyin. Örneğin, aşağıdaki kod AJAX aracılığıyla eklenen bir formda istemci tarafı doğrulamayı ayarlar.

$.get({
    url: "https://url/that/returns/a/form",
    dataType: "html",
    error: function(jqXHR, textStatus, errorThrown) {
        alert(textStatus + ": Couldn't add form. " + errorThrown);
    },
    success: function(newFormHTML) {
        var container = document.getElementById("form-container");
        container.insertAdjacentHTML("beforeend", newFormHTML);
        var forms = container.getElementsByTagName("form");
        var newForm = forms[forms.length - 1];
        $.validator.unobtrusive.parse(newForm);
    }
})

yöntemi, $.validator.unobtrusive.parse() tek bağımsız değişkeni için bir jQuery seçicisi kabul eder. Bu yöntem jQuery Unobtrusive Validation'a bu seçici içindeki data- formların özniteliklerini ayrıştırmalarını söyler. Daha sonra bu özniteliklerin değerleri jQuery Doğrulama eklentisine geçirilir.

Dinamik Denetimlere Doğrulama Ekleme

$.validator.unobtrusive.parse() yöntemi, ve <select/>gibi <input> dinamik olarak oluşturulan tek tek denetimlerde değil, formun tamamında çalışır. Formu yeniden ayrıştırmak için, aşağıdaki örnekte gösterildiği gibi, form daha önce ayrıştırıldığında eklenen doğrulama verilerini kaldırın:

$.get({
    url: "https://url/that/returns/a/control",
    dataType: "html",
    error: function(jqXHR, textStatus, errorThrown) {
        alert(textStatus + ": Couldn't add control. " + errorThrown);
    },
    success: function(newInputHTML) {
        var form = document.getElementById("my-form");
        form.insertAdjacentHTML("beforeend", newInputHTML);
        $(form).removeData("validator")    // Added by jQuery Validation
               .removeData("unobtrusiveValidation");   // Added by jQuery Unobtrusive Validation
        $.validator.unobtrusive.parse(form);
    }
})

Özel istemci tarafı doğrulama

Özel istemci tarafı doğrulama, özel bir jQuery Doğrulama bağdaştırıcısıyla çalışan HTML öznitelikleri oluşturularak data- yapılır. Bu makalenin [ClassicMovie] önceki bölümlerinde tanıtılan ve [ClassicMovieWithClientValidator] öznitelikleri için aşağıdaki örnek bağdaştırıcı kodu yazılmıştır:

$.validator.addMethod('classicmovie', function (value, element, params) {
    var genre = $(params[0]).val(), year = params[1], date = new Date(value);

    // The Classic genre has a value of '0'.
    if (genre && genre.length > 0 && genre[0] === '0') {
        // The release date for a Classic is valid if it's no greater than the given year.
        return date.getUTCFullYear() <= year;
    }

    return true;
});

$.validator.unobtrusive.adapters.add('classicmovie', ['year'], function (options) {
    var element = $(options.form).find('select#Movie_Genre')[0];

    options.rules['classicmovie'] = [element, parseInt(options.params['year'])];
    options.messages['classicmovie'] = options.message;
});

Bağdaştırıcı yazma hakkında bilgi için bkz . jQuery Doğrulama belgeleri.

Belirli bir alan için bağdaştırıcı kullanımı şu öznitelikler tarafından data- tetikleniyor:

  • Alana doğrulamaya (data-val="true") tabi olarak bayrak ekleyin.
  • Doğrulama kuralı adını ve hata iletisi metnini (örneğin, data-val-rulename="Error message.") tanımlayın.
  • Doğrulayıcının ihtiyaç duyduğu ek parametreleri sağlayın (örneğin, data-val-rulename-param1="value").

Aşağıdaki örnekte örnek uygulamanın özniteliğinin öznitelikleri gösterilmektedir data- ClassicMovie:

<input class="form-control" type="date"
    data-val="true"
    data-val-classicmovie="Classic movies must have a release year no later than 1960."
    data-val-classicmovie-year="1960"
    data-val-required="The Release Date field is required."
    id="Movie_ReleaseDate" name="Movie.ReleaseDate" value="">

Daha önce belirtildiği gibi, Etiket Yardımcıları ve HTML yardımcıları öznitelikleri işlemek data- için doğrulama özniteliklerinden bilgileri kullanır. Kod yazmak için özel data- HTML özniteliklerinin oluşturulmasına neden olan iki seçenek vardır:

  • öğesinden AttributeAdapterBase<TAttribute> türetilen ve öğesini uygulayan IValidationAttributeAdapterProviderbir sınıf oluşturun ve özniteliğinizi ve bağdaştırıcısını DI'ye kaydedin. Bu yöntem, sunucuyla ilgili ve istemciyle ilgili doğrulama kodunun ayrı sınıflarda yer alan tek sorumluluk ilkesini izler. Bağdaştırıcı, DI'ye kayıtlı olduğundan, gerekirse DI'deki diğer hizmetlerin de kullanılabilir olması avantajına da sahiptir.
  • Sınıfınızda ValidationAttribute uygulayınIClientModelValidator. Bu yöntem, özniteliği sunucu tarafı doğrulaması yapmıyorsa ve DI'den herhangi bir hizmete ihtiyaç duymadığında uygun olabilir.

İstemci tarafı doğrulaması için AttributeAdapter

HTML'de öznitelikleri işlemenin data- bu yöntemi, örnek uygulamadaki özniteliği tarafından ClassicMovie kullanılır. Bu yöntemi kullanarak istemci doğrulaması eklemek için:

  1. Özel doğrulama özniteliği için bir öznitelik bağdaştırıcısı sınıfı oluşturun. sınıfından türetilir AttributeAdapterBase<TAttribute>. Bu örnekte gösterildiği gibi işlenen çıkışa öznitelik ekleyen data- bir AddValidation yöntem oluşturun:

    public class ClassicMovieAttributeAdapter : AttributeAdapterBase<ClassicMovieAttribute>
    {
        public ClassicMovieAttributeAdapter(
            ClassicMovieAttribute attribute, IStringLocalizer? stringLocalizer)
            : base(attribute, stringLocalizer)
        {
    
        }
    
        public override void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage(context));
    
            var year = Attribute.Year.ToString(CultureInfo.InvariantCulture);
            MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
        }
    
        public override string GetErrorMessage(ModelValidationContextBase validationContext)
            => Attribute.GetErrorMessage();
    }
    
  2. uygulayan IValidationAttributeAdapterProviderbir bağdaştırıcı sağlayıcı sınıfı oluşturun. GetAttributeAdapter yönteminde, bu örnekte gösterildiği gibi bağdaştırıcının oluşturucusunun özel özniteliğini geçirin:

    public class CustomValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider
    {
        private readonly IValidationAttributeAdapterProvider baseProvider =
            new ValidationAttributeAdapterProvider();
    
        public IAttributeAdapter? GetAttributeAdapter(
            ValidationAttribute attribute, IStringLocalizer? stringLocalizer)
        {
            if (attribute is ClassicMovieAttribute classicMovieAttribute)
            {
                return new ClassicMovieAttributeAdapter(classicMovieAttribute, stringLocalizer);
            }
    
            return baseProvider.GetAttributeAdapter(attribute, stringLocalizer);
        }
    }
    
  3. içinde DI için bağdaştırıcı sağlayıcısını Program.cskaydedin:

    builder.Services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.MaxModelValidationErrors = 50;
            options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
                _ => "The field is required.");
        });
    
    builder.Services.AddSingleton
        <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
    

İstemci tarafı doğrulaması için IClientModelValidator

HTML'de öznitelikleri işlemenin data- bu yöntemi, örnek uygulamadaki özniteliği tarafından ClassicMovieWithClientValidator kullanılır. Bu yöntemi kullanarak istemci doğrulaması eklemek için:

  • Özel doğrulama özniteliğinde arabirimini IClientModelValidator uygulayın ve bir AddValidation yöntem oluşturun. yönteminde AddValidation , aşağıdaki örnekte gösterildiği gibi doğrulama öznitelikleri ekleyin data- :

    public class ClassicMovieWithClientValidatorAttribute :
        ValidationAttribute, IClientModelValidator
    {
        public ClassicMovieWithClientValidatorAttribute(int year)
            => Year = year;
    
        public int Year { get; }
    
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage());
    
            var year = Year.ToString(CultureInfo.InvariantCulture);
            MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
        }
    
        public string GetErrorMessage() =>
            $"Classic movies must have a release year no later than {Year}.";
    
        protected override ValidationResult? IsValid(
            object? value, ValidationContext validationContext)
        {
            var movie = (Movie)validationContext.ObjectInstance;
            var releaseYear = ((DateTime)value!).Year;
    
            if (movie.Genre == Genre.Classic && releaseYear > Year)
            {
                return new ValidationResult(GetErrorMessage());
            }
    
            return ValidationResult.Success;
        }
    
        private static bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
    
            attributes.Add(key, value);
            return true;
        }
    }
    

İstemci tarafı doğrulamayı devre dışı bırakma

Aşağıdaki kod, Sayfalar'da Razor istemci doğrulamasını devre dışı bırakır:

builder.Services.AddRazorPages()
    .AddViewOptions(options =>
    {
        options.HtmlHelperOptions.ClientValidationEnabled = false;
    });

İstemci tarafı doğrulamasını devre dışı bırakmak için diğer seçenekler:

  • Başvuruyu _ValidationScriptsPartial tüm dosyalarda açıklama satırı oluşturun .cshtml .
  • Pages\Shared_ValidationScriptsPartial.cshtml dosyasının içeriğini kaldırın.

Yukarıdaki yaklaşım, ASP.NET Core IdentityRazor sınıf kitaplığının istemci tarafı doğrulamasını engellemez. Daha fazla bilgi için bkz. ASP.NET Core projelerinde yapı iskelesiIdentity.

Sorun ayrıntıları

Sorun Ayrıntıları , HTTP API hatasını açıklayan tek yanıt biçimi değildir, ancak genellikle HTTP API'lerine yönelik hataları bildirmek için kullanılır.

Sorun ayrıntıları hizmeti, ASP.NET Core'da sorun ayrıntıları oluşturmayı destekleyen arabirimini uygular IProblemDetailsService . AddProblemDetails(IServiceCollection) üzerindeki IServiceCollection uzantı yöntemi, varsayılan IProblemDetailsService uygulamayı kaydeder.

ASP.NET Core uygulamalarında, istek HTTP üst bilgisinin kayıtlı tarafından desteklenen içerik türlerinden birini içermemesiAccept dışında, aşağıdaki ara yazılım çağrıldığında AddProblemDetails sorun ayrıntıları HTTP yanıtları oluşturur (varsayılan: application/json):IProblemDetailsWriter

Ek kaynaklar

Bu makalede, ASP.NET Core MVC veya Razor Pages uygulamasında kullanıcı girişinin nasıl doğrulanması açıklanır.

Örnek kodu görüntüleme veya indirme (indirme).

Model durumu

Model durumu, iki alt sistemden gelen hataları temsil eder: model bağlama ve model doğrulama. Model bağlamasından kaynaklanan hatalar genellikle veri dönüştürme hatalarıdır. Örneğin, bir tamsayı alanına "x" girilir. Model doğrulama, model bağlamadan sonra gerçekleşir ve verilerin iş kurallarına uymadığı hataları bildirir. Örneğin, derecelendirmenin 1 ile 5 arasında olmasını bekleyen bir alana 0 girilir.

Hem model bağlama hem de model doğrulama, bir denetleyici eyleminin veya Razor Pages işleyici yönteminin yürütülmesinden önce gerçekleşir. Web uygulamaları için uygun şekilde incelemek ModelState.IsValid ve tepki vermek uygulamanın sorumluluğundadır. Web uygulamaları genellikle aşağıdaki Razor Sayfalar örneğinde gösterildiği gibi sayfayı bir hata iletisiyle yeniden görüntüler:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movies.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Denetleyiciler ve görünümler içeren ASP.NET Core MVC için, aşağıdaki örnekte bir denetleyici eyleminin içinde nasıl denetlenecek ModelState.IsValid gösterilmektedir:

public async Task<IActionResult> Create(Movie movie)
{
    if (!ModelState.IsValid)
    {
        return View(movie);
    }

    _context.Movies.Add(movie);
    await _context.SaveChangesAsync();

    return RedirectToAction(nameof(Index));
}

Web API denetleyicilerinin [ApiController] özniteliğine sahip olup olmadığını denetlemeleri ModelState.IsValid gerekmez. Bu durumda, model durumu geçersiz olduğunda hata ayrıntılarını içeren otomatik bir HTTP 400 yanıtı döndürülür. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

Doğrulamayı yeniden çalıştırma

Doğrulama otomatiktir, ancak el ile yinelemek isteyebilirsiniz. Örneğin, bir özellik için bir değer hesaplayabilirsiniz ve özelliği hesaplanan değere ayarladıktan sonra doğrulamayı yeniden çalıştırmak isteyebilirsiniz. Doğrulamayı yeniden çalıştırmak için, doğrulanan modele özgü doğrulamayı temizlemek için öğesini ve ardından TryValidateModelöğesini çağırınModelStateDictionary.ClearValidationState:

public async Task<IActionResult> OnPostTryValidateAsync()
{
    var modifiedReleaseDate = DateTime.Now.Date;
    Movie.ReleaseDate = modifiedReleaseDate;

    ModelState.ClearValidationState(nameof(Movie));
    if (!TryValidateModel(Movie, nameof(Movie)))
    {
        return Page();
    }

    _context.Movies.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Doğrulama öznitelikleri

Doğrulama öznitelikleri, model özellikleri için doğrulama kuralları belirtmenize olanak sağlar. Örnek uygulamadan alınan aşağıdaki örnekte, doğrulama öznitelikleriyle açıklama eklenen bir model sınıfı gösterilmektedir. [ClassicMovie] özniteliği özel bir doğrulama özniteliğidir ve diğerleri yerleşiktir. gösterilmez, [ClassicMovieWithClientValidator]bu da özel bir öznitelik uygulamak için alternatif bir yol gösterir.

public class Movie
{
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; } = null!;

    [ClassicMovie(1960)]
    [DataType(DataType.Date)]
    [Display(Name = "Release Date")]
    public DateTime ReleaseDate { get; set; }

    [Required]
    [StringLength(1000)]
    public string Description { get; set; } = null!;

    [Range(0, 999.99)]
    public decimal Price { get; set; }

    public Genre Genre { get; set; }

    public bool Preorder { get; set; }
}

Yerleşik öznitelikler

Yerleşik doğrulama özniteliklerinden bazıları şunlardır:

  • [ValidateNever]: Bir özelliğin veya parametrenin doğrulamanın dışında tutulması gerektiğini gösterir.
  • [CreditCard]: Özelliğin kredi kartı biçiminde olduğunu doğrular. jQuery Doğrulama Ek Yöntemleri gerektirir.
  • [Karşılaştır]: Modeldeki iki özelliğin eşleştiklerini doğrular.
  • [EmailAddress]: Özelliğin e-posta biçimi olduğunu doğrular.
  • [Telefon]: Özelliğin telefon numarası biçimine sahip olduğunu doğrular.
  • [Aralık]: Özellik değerinin belirtilen aralık içinde olduğunu doğrular.
  • [RegularExpression]: Özellik değerinin belirtilen normal ifadeyle eşleştiklerini doğrular.
  • [Gerekli]: Alanın null olmadığını doğrular. Bu özniteliğin davranışıyla ilgili ayrıntılar için bkz [Required] . öznitelik .
  • [StringLength]: Dize özellik değerinin belirtilen uzunluk sınırını aşmadığını doğrular.
  • [Url]: Özelliğin BIR URL biçimi olduğunu doğrular.
  • [Uzak]: Sunucuda bir eylem yöntemi çağırarak istemcideki girişi doğrular. Bu özniteliğin davranışıyla ilgili ayrıntılar için bkz [Remote] . öznitelik .

Doğrulama özniteliklerinin tam listesi ad alanında System.ComponentModel.DataAnnotations bulunabilir.

Hata iletileri

Doğrulama öznitelikleri, geçersiz giriş için görüntülenecek hata iletisini belirtmenize olanak sağlar. Örneğin:

[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]

Öznitelikler dahili olarak, alan adı ve bazen ek yer tutucular için bir yer tutucu ile çağrır String.Format . Örneğin:

[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]

Bir Name özelliğe uygulandığında, önceki kod tarafından oluşturulan hata iletisi "Ad uzunluğu 6 ile 8 arasında olmalıdır".

Belirli bir özniteliğin hata iletisi için hangi parametrelerin geçirildiğini String.Format öğrenmek için Bkz . DataAnnotations kaynak kodu.

Null değer atanamayan başvuru türleri ve [Required] özniteliği

Doğrulama sistemi, null değer atanamayan parametreleri veya ilişkili özellikleri bir [Required(AllowEmptyStrings = true)] özniteliği varmış gibi ele alır. MVC, bağlamları etkinleştirerekNullable, genel olmayan türlerde veya parametrelerde null atanamayan özellikleri özniteliğiyle ilişkilendirilmiş gibi örtük olarak doğrulamaya [Required(AllowEmptyStrings = true)] başlar. Aşağıdaki kodu inceleyin:

public class Person
{
    public string Name { get; set; }
}

Uygulama ile <Nullable>enable</Nullable>oluşturulduysa, JSON veya form gönderisinde için Name eksik bir değer doğrulama hatasıyla sonuçlanır. Özelliği için null veya eksik değerlerin belirtilmesine izin vermek için Name null atanabilir bir başvuru türü kullanın:

public class Person
{
    public string? Name { get; set; }
}

Bu davranış, içinde Program.csyapılandırılarak SuppressImplicitRequiredAttributeForNonNullableReferenceTypes devre dışı bırakılabilir:

builder.Services.AddControllers(
    options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);

Genel türlerde ve [Gerekli] özniteliğinde null atanamayan özellikler

Genel türlerdeki null atanamaz özellikler, tür gerektiğinde özniteliği içermelidir [Required] . Aşağıdaki kodda TestRequired gerekli değildir:

public class WeatherForecast<T>
{
    public string TestRequired { get; set; } = null!;
    public T? Inner { get; set; }
}

Aşağıdaki kodda açıkça TestRequired gerekli olarak işaretlenir:

using System.ComponentModel.DataAnnotations;

public class WeatherForecast<T>
{
    [Required]
    public string TestRequired { get; set; } = null!;
    public T? Inner { get; set; }
}

Sunucuda [Gerekli] doğrulama

Sunucuda, özellik null olduğunda gerekli bir değerin eksik olduğu kabul edilir. Null değer atanamayan bir alan her zaman geçerlidir ve özniteliğin [Required] hata iletisi hiçbir zaman görüntülenmez.

Ancak, null değer atanamayan bir özellik için model bağlama başarısız olabilir ve gibi The value '' is invalidbir hata iletisiyle sonuçlanabilir. Null değer atanamayan türlerin sunucu tarafı doğrulaması için özel bir hata iletisi belirtmek için aşağıdaki seçeneklere sahipsiniz:

  • Alanı null atanabilir hale getirin (örneğin, decimal? yerine decimal). Null atanabilir<T> değer türleri standart null atanabilir türler olarak kabul edilir.

  • Aşağıdaki örnekte gösterildiği gibi model bağlaması tarafından kullanılacak varsayılan hata iletisini belirtin:

    builder.Services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.MaxModelValidationErrors = 50;
            options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
                _ => "The field is required.");
        });
    
    builder.Services.AddSingleton
        <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
    

    Varsayılan iletileri ayarlayabileceğiniz model bağlama hataları hakkında daha fazla bilgi için bkz DefaultModelBindingMessageProvider. .

İstemcide [Gerekli] doğrulama

Null değer atanamayan türler ve dizeler istemcide sunucuyla karşılaştırıldığında farklı şekilde işlenir. İstemcide:

  • Bir değerin mevcut olduğu kabul edilir, ancak bu değer için giriş girilirse. Bu nedenle, istemci tarafı doğrulama null atanamayan türleri null atanabilir türlerle aynı şekilde işler.
  • Dize alanındaki boşluk, jQuery Doğrulaması gerekli yöntemi tarafından geçerli giriş olarak kabul edilir. Sunucu tarafı doğrulaması, yalnızca boşluk girilirse gerekli dize alanını geçersiz sayıyor.

Daha önce belirtildiği gibi, null atanamayan türler bir [Required(AllowEmptyStrings = true)] özniteliği varmış gibi kabul edilir. Bu, özniteliğini uygulamasanız bile istemci tarafı doğrulamasını [Required(AllowEmptyStrings = true)] alabileceğiniz anlamına gelir. Ancak özniteliğini kullanmazsanız varsayılan bir hata iletisi alırsınız. Özel bir hata iletisi belirtmek için özniteliğini kullanın.

[Remote] özniteliği

[Remote] özniteliği, alan girişinin geçerli olup olmadığını belirlemek için sunucuda bir yöntem çağırmayı gerektiren istemci tarafı doğrulaması uygular. Örneğin, uygulamanın bir kullanıcı adının zaten kullanımda olup olmadığını doğrulaması gerekebilir.

Uzaktan doğrulama uygulamak için:

  1. JavaScript'in çağıracağı bir eylem yöntemi oluşturun. jQuery Doğrulama uzak yöntemi bir JSON yanıtı bekler:

    • true giriş verilerinin geçerli olduğu anlamına gelir.
    • false, undefinedveya null girişin geçersiz olduğu anlamına gelir. Varsayılan hata iletisini görüntüleyin.
    • Diğer dizeler girişin geçersiz olduğu anlamına gelir. Dizeyi özel bir hata iletisi olarak görüntüleyin.

    Aşağıda özel hata iletisi döndüren bir eylem yöntemi örneği verilmiştir:

    [AcceptVerbs("GET", "POST")]
    public IActionResult VerifyEmail(string email)
    {
        if (!_userService.VerifyEmail(email))
        {
            return Json($"Email {email} is already in use.");
        }
    
        return Json(true);
    }
    
  2. Model sınıfında, aşağıdaki örnekte gösterildiği gibi doğrulama eylemi yöntemine işaret eden bir [Remote] öznitelikle özelliğine açıklama ekleyin:

    [Remote(action: "VerifyEmail", controller: "Users")]
    public string Email { get; set; } = null!;
    

Ek alanlar

AdditionalFields özniteliğinin [Remote] özelliği, sunucudaki verilerde alan birleşimlerini doğrulamanıza olanak tanır. Örneğin, modelde User FirstName ve LastName özellikleri varsa, mevcut kullanıcıların bu ad çiftine sahip olmadığını doğrulamak isteyebilirsiniz. Aşağıdaki örnekte nasıl kullanılacağı gösterilmektedir AdditionalFields:

[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(LastName))]
[Display(Name = "First Name")]
public string FirstName { get; set; } = null!;

[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(FirstName))]
[Display(Name = "Last Name")]
public string LastName { get; set; } = null!;

AdditionalFieldsaçıkça "FirstName" ve "LastName" dizelerine ayarlanabilir, ancak nameof işlecinin kullanılması daha sonra yeniden düzenlemeyi kolaylaştırır. Bu doğrulama için eylem yöntemi hem hem de firstName lastName bağımsız değişkenlerini kabul etmelidir:

[AcceptVerbs("GET", "POST")]
public IActionResult VerifyName(string firstName, string lastName)
{
    if (!_userService.VerifyName(firstName, lastName))
    {
        return Json($"A user named {firstName} {lastName} already exists.");
    }

    return Json(true);
}

Kullanıcı bir ad veya soyadı girdiğinde, JavaScript bu ad çiftinin alınıp alınmadığını görmek için uzak bir çağrı yapar.

İki veya daha fazla ek alanı doğrulamak için, bunları virgülle ayrılmış liste olarak sağlayın. Örneğin, modele özellik MiddleName eklemek için özniteliğini [Remote] aşağıdaki örnekte gösterildiği gibi ayarlayın:

[Remote(action: "VerifyName", controller: "Users",
    AdditionalFields = nameof(FirstName) + "," + nameof(LastName))]
public string MiddleName { get; set; }

AdditionalFields, tüm öznitelik bağımsız değişkenleri gibi sabit bir ifade olmalıdır. Bu nedenle, başlatmak AdditionalFieldsiçin ilişkilendirilmiş bir dize veya çağrı Join kullanmayın.

Yerleşik özniteliklere alternatifler

Yerleşik öznitelikler tarafından sağlanmayan doğrulamaya ihtiyacınız varsa şunları yapabilirsiniz:

Özel öznitelikler

Yerleşik doğrulama özniteliklerinin işlemediğini senaryolar için özel doğrulama öznitelikleri oluşturabilirsiniz. öğesinden ValidationAttributedevralan bir sınıf oluşturun ve yöntemini geçersiz kılın IsValid .

IsValid yöntemi, doğrulanacak giriş olan value adlı bir nesneyi kabul eder. Aşırı yükleme, model bağlaması tarafından oluşturulan model örneği gibi ek bilgiler sağlayan bir ValidationContext nesneyi de kabul eder.

Aşağıdaki örnek, Klasik tarzdaki bir filmin yayın tarihinin belirtilen yıldan sonra olmadığını doğrular. Özniteliği [ClassicMovie] :

  • Yalnızca sunucuda çalıştırılır.
  • Klasik filmler için yayın tarihini doğrular:
public class ClassicMovieAttribute : ValidationAttribute
{
    public ClassicMovieAttribute(int year)
        => Year = year;

    public int Year { get; }

    public string GetErrorMessage() =>
        $"Classic movies must have a release year no later than {Year}.";

    protected override ValidationResult? IsValid(
        object? value, ValidationContext validationContext)
    {
        var movie = (Movie)validationContext.ObjectInstance;
        var releaseYear = ((DateTime)value!).Year;

        if (movie.Genre == Genre.Classic && releaseYear > Year)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }
}

movie Yukarıdaki örnekteki değişken, form gönderimindeki verileri içeren bir Movie nesneyi temsil eder. Doğrulama başarısız olduğunda, ValidationResult hata iletisi içeren bir döndürülür.

IValidatableObject

Yukarıdaki örnek yalnızca türlerle Movie çalışır. Sınıf düzeyi doğrulama için bir diğer seçenek de aşağıdaki örnekte gösterildiği gibi model sınıfında uygulamaktır IValidatableObject :

public class ValidatableMovie : IValidatableObject
{
    private const int _classicYear = 1960;

    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; } = null!;

    [DataType(DataType.Date)]
    [Display(Name = "Release Date")]
    public DateTime ReleaseDate { get; set; }

    [Required]
    [StringLength(1000)]
    public string Description { get; set; } = null!;

    [Range(0, 999.99)]
    public decimal Price { get; set; }

    public Genre Genre { get; set; }

    public bool Preorder { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Genre == Genre.Classic && ReleaseDate.Year > _classicYear)
        {
            yield return new ValidationResult(
                $"Classic movies must have a release year no later than {_classicYear}.",
                new[] { nameof(ReleaseDate) });
        }
    }
}

Üst düzey düğüm doğrulama

En üst düzey düğümler şunlardır:

  • İşlem parametreleri
  • Denetleyici özellikleri
  • Sayfa işleyicisi parametreleri
  • Sayfa modeli özellikleri

Modele bağlı üst düzey düğümler, model özelliklerini doğrulamaya ek olarak doğrulanır. Örnek uygulamadan aşağıdaki örnekte yöntemi, VerifyPhone eylem parametresini doğrulamak phone için öğesini RegularExpressionAttribute kullanır:

[AcceptVerbs("GET", "POST")]
public IActionResult VerifyPhone(
    [RegularExpression(@"^\d{3}-\d{3}-\d{4}$")] string phone)
{
    if (!ModelState.IsValid)
    {
        return Json($"Phone {phone} has an invalid format. Format: ###-###-####");
    }

    return Json(true);
}

Üst düzey düğümler doğrulama öznitelikleriyle kullanabilir BindRequiredAttribute . Örnek uygulamadan alınan aşağıdaki örnekte yöntemi, CheckAge form gönderildiğinde parametrenin age sorgu dizesinden bağlanması gerektiğini belirtir:

[HttpPost]
public IActionResult CheckAge([BindRequired, FromQuery] int age)
{

Yaşı Denetle sayfasında ()CheckAge.cshtml iki form vardır. İlk form değerini Age 99 sorgu dizesi parametresi olarak gönderir: https://localhost:5001/Users/CheckAge?Age=99.

Sorgu dizesinden düzgün biçimlendirilmiş age bir parametre gönderildiğinde, form doğrulanır.

Yaşı Denetle sayfasındaki ikinci form, isteğin Age gövdesindeki değeri gönderir ve doğrulama başarısız olur. Parametrenin bir sorgu dizesinden gelmesi gerektiğinden age bağlama başarısız oluyor.

En fazla hata sayısı

Maksimum hata sayısına (varsayılan olarak 200) ulaşıldığında doğrulama durdurulur. Bu sayıyı içinde Program.csaşağıdaki kodla yapılandırabilirsiniz:

builder.Services.AddRazorPages()
    .AddMvcOptions(options =>
    {
        options.MaxModelValidationErrors = 50;
        options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
            _ => "The field is required.");
    });

builder.Services.AddSingleton
    <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();

En fazla özyineleme

ValidationVisitor doğrulanan modelin nesne grafını gezer. Derin veya sonsuz özyinelemeli modeller için doğrulama, yığın taşmasına neden olabilir. MvcOptions.MaxValidationDepth , ziyaretçi özyinelemesi yapılandırılmış bir derinliği aşarsa doğrulamayı erken durdurmanın bir yolunu sağlar. varsayılan değeri MvcOptions.MaxValidationDepth 32'dir.

Otomatik kısa devre

Model grafı doğrulama gerektirmiyorsa doğrulama otomatik olarak kısa devreli (atlanır) olur. Çalışma zamanının doğrulamayı atlayan nesneleri, temel öğe koleksiyonlarını (, byte[]string[], Dictionary<string, string>gibi) ve herhangi bir doğrulayıcı içermeyen karmaşık nesne graflarını içerir.

İstemci tarafı doğrulama

İstemci tarafı doğrulama, form geçerli olana kadar gönderimi engeller. Gönder düğmesi formu gönderen veya hata iletileri görüntüleyen JavaScript'i çalıştırır.

İstemci tarafı doğrulama, formda giriş hataları olduğunda sunucuya gereksiz bir gidiş dönüşten kaçınıyor. aşağıdaki betik başvuruları ve _Layout.cshtml _ValidationScriptsPartial.cshtml istemci tarafı doğrulamasını destekler:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.12/jquery.validate.unobtrusive.js"></script>

jQuery Göze Çarpmayan Doğrulama betiği, popüler jQuery Doğrulama eklentisini kullanan özel bir Microsoft ön uç kitaplığıdır. jQuery Göze Çarpmayan Doğrulama olmadan aynı doğrulama mantığını iki yerde kodlasanız: model özelliklerindeki sunucu tarafı doğrulama özniteliklerine ve ardından istemci tarafı betiklerine bir kez daha. Bunun yerine, Etiket Yardımcıları ve HTML yardımcıları doğrulama gerektiren form öğeleri için HTML 5 data- özniteliklerini işlemek üzere doğrulama özniteliklerini kullanır ve model özelliklerinden meta verileri yazar. jQuery Göze Çarpmayan Doğrulama, öznitelikleri ayrıştırarak data- mantığı jQuery Doğrulaması'na geçirir ve sunucu tarafı doğrulama mantığını istemciye etkili bir şekilde "kopyalar". Burada gösterildiği gibi etiket yardımcılarını kullanarak istemcide doğrulama hataları görüntüleyebilirsiniz:

<div class="form-group">
    <label asp-for="Movie.ReleaseDate" class="control-label"></label>
    <input asp-for="Movie.ReleaseDate" class="form-control" />
    <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
</div>

Yukarıdaki etiket yardımcıları aşağıdaki HTML'yi işler:

<div class="form-group">
    <label class="control-label" for="Movie_ReleaseDate">Release Date</label>
    <input class="form-control" type="date" data-val="true"
        data-val-required="The Release Date field is required."
        id="Movie_ReleaseDate" name="Movie.ReleaseDate" value="">
    <span class="text-danger field-validation-valid"
        data-valmsg-for="Movie.ReleaseDate" data-valmsg-replace="true"></span>
</div>

HTML çıkışındaki data- özniteliklerin özelliği için doğrulama özniteliklerine Movie.ReleaseDate karşılık geldiğini fark edin. Özniteliği, data-val-required kullanıcı yayın tarihi alanını doldurmazsa görüntülenecek bir hata iletisi içerir. jQuery Göze Çarpmayan Doğrulama bu değeri jQuery Validation required() yöntemine geçirir ve bu yöntem bu iletiyi eşlik eden <span> öğesinde görüntüler.

Veri türü doğrulaması, [DataType] özniteliği tarafından geçersiz kılınmadığı sürece bir özelliğin .NET türünü temel alır. Tarayıcıların kendi varsayılan hata iletileri vardır, ancak jQuery Doğrulama Engelleyici Olmayan Doğrulama paketi bu iletileri geçersiz kılabilir. [DataType]öznitelikleri ve [EmailAddress] gibi alt sınıflar hata iletisini belirtmenize olanak sağlar.

Göze çarpmayan doğrulama

Engelleyici olmayan doğrulama hakkında bilgi için bu GitHub sorununa bakın.

Dinamik Formlara Doğrulama Ekleme

jQuery Göze Çarpmayan Doğrulama, sayfa ilk yüklendiğinde doğrulama mantığını ve parametrelerini jQuery Doğrulaması'na geçirir. Bu nedenle doğrulama, dinamik olarak oluşturulan formlarda otomatik olarak çalışmaz. Doğrulamayı etkinleştirmek için jQuery Engelleyici Olmayan Doğrulama'ya dinamik formu oluşturduktan hemen sonra ayrıştırmasını söyleyin. Örneğin, aşağıdaki kod AJAX aracılığıyla eklenen bir formda istemci tarafı doğrulamayı ayarlar.

$.get({
    url: "https://url/that/returns/a/form",
    dataType: "html",
    error: function(jqXHR, textStatus, errorThrown) {
        alert(textStatus + ": Couldn't add form. " + errorThrown);
    },
    success: function(newFormHTML) {
        var container = document.getElementById("form-container");
        container.insertAdjacentHTML("beforeend", newFormHTML);
        var forms = container.getElementsByTagName("form");
        var newForm = forms[forms.length - 1];
        $.validator.unobtrusive.parse(newForm);
    }
})

yöntemi, $.validator.unobtrusive.parse() tek bağımsız değişkeni için bir jQuery seçicisi kabul eder. Bu yöntem jQuery Unobtrusive Validation'a bu seçici içindeki data- formların özniteliklerini ayrıştırmalarını söyler. Daha sonra bu özniteliklerin değerleri jQuery Doğrulama eklentisine geçirilir.

Dinamik Denetimlere Doğrulama Ekleme

$.validator.unobtrusive.parse() yöntemi, ve <select/>gibi <input> dinamik olarak oluşturulan tek tek denetimlerde değil, formun tamamında çalışır. Formu yeniden ayrıştırmak için, aşağıdaki örnekte gösterildiği gibi, form daha önce ayrıştırıldığında eklenen doğrulama verilerini kaldırın:

$.get({
    url: "https://url/that/returns/a/control",
    dataType: "html",
    error: function(jqXHR, textStatus, errorThrown) {
        alert(textStatus + ": Couldn't add control. " + errorThrown);
    },
    success: function(newInputHTML) {
        var form = document.getElementById("my-form");
        form.insertAdjacentHTML("beforeend", newInputHTML);
        $(form).removeData("validator")    // Added by jQuery Validation
               .removeData("unobtrusiveValidation");   // Added by jQuery Unobtrusive Validation
        $.validator.unobtrusive.parse(form);
    }
})

Özel istemci tarafı doğrulama

Özel istemci tarafı doğrulama, özel bir jQuery Doğrulama bağdaştırıcısıyla çalışan HTML öznitelikleri oluşturularak data- yapılır. Bu makalenin [ClassicMovie] önceki bölümlerinde tanıtılan ve [ClassicMovieWithClientValidator] öznitelikleri için aşağıdaki örnek bağdaştırıcı kodu yazılmıştır:

$.validator.addMethod('classicmovie', function (value, element, params) {
    var genre = $(params[0]).val(), year = params[1], date = new Date(value);

    // The Classic genre has a value of '0'.
    if (genre && genre.length > 0 && genre[0] === '0') {
        // The release date for a Classic is valid if it's no greater than the given year.
        return date.getUTCFullYear() <= year;
    }

    return true;
});

$.validator.unobtrusive.adapters.add('classicmovie', ['year'], function (options) {
    var element = $(options.form).find('select#Movie_Genre')[0];

    options.rules['classicmovie'] = [element, parseInt(options.params['year'])];
    options.messages['classicmovie'] = options.message;
});

Bağdaştırıcı yazma hakkında bilgi için bkz . jQuery Doğrulama belgeleri.

Belirli bir alan için bağdaştırıcı kullanımı şu öznitelikler tarafından data- tetikleniyor:

  • Alana doğrulamaya (data-val="true") tabi olarak bayrak ekleyin.
  • Doğrulama kuralı adını ve hata iletisi metnini (örneğin, data-val-rulename="Error message.") tanımlayın.
  • Doğrulayıcının ihtiyaç duyduğu ek parametreleri sağlayın (örneğin, data-val-rulename-param1="value").

Aşağıdaki örnekte örnek uygulamanın özniteliğinin öznitelikleri gösterilmektedir data- ClassicMovie:

<input class="form-control" type="date"
    data-val="true"
    data-val-classicmovie="Classic movies must have a release year no later than 1960."
    data-val-classicmovie-year="1960"
    data-val-required="The Release Date field is required."
    id="Movie_ReleaseDate" name="Movie.ReleaseDate" value="">

Daha önce belirtildiği gibi, Etiket Yardımcıları ve HTML yardımcıları öznitelikleri işlemek data- için doğrulama özniteliklerinden bilgileri kullanır. Kod yazmak için özel data- HTML özniteliklerinin oluşturulmasına neden olan iki seçenek vardır:

  • öğesinden AttributeAdapterBase<TAttribute> türetilen ve öğesini uygulayan IValidationAttributeAdapterProviderbir sınıf oluşturun ve özniteliğinizi ve bağdaştırıcısını DI'ye kaydedin. Bu yöntem, sunucuyla ilgili ve istemciyle ilgili doğrulama kodunun ayrı sınıflarda yer alan tek sorumluluk ilkesini izler. Bağdaştırıcı, DI'ye kayıtlı olduğundan, gerekirse DI'deki diğer hizmetlerin de kullanılabilir olması avantajına da sahiptir.
  • Sınıfınızda ValidationAttribute uygulayınIClientModelValidator. Bu yöntem, özniteliği sunucu tarafı doğrulaması yapmıyorsa ve DI'den herhangi bir hizmete ihtiyaç duymadığında uygun olabilir.

İstemci tarafı doğrulaması için AttributeAdapter

HTML'de öznitelikleri işlemenin data- bu yöntemi, örnek uygulamadaki özniteliği tarafından ClassicMovie kullanılır. Bu yöntemi kullanarak istemci doğrulaması eklemek için:

  1. Özel doğrulama özniteliği için bir öznitelik bağdaştırıcısı sınıfı oluşturun. sınıfından türetilir AttributeAdapterBase<TAttribute>. Bu örnekte gösterildiği gibi işlenen çıkışa öznitelik ekleyen data- bir AddValidation yöntem oluşturun:

    public class ClassicMovieAttributeAdapter : AttributeAdapterBase<ClassicMovieAttribute>
    {
        public ClassicMovieAttributeAdapter(
            ClassicMovieAttribute attribute, IStringLocalizer? stringLocalizer)
            : base(attribute, stringLocalizer)
        {
    
        }
    
        public override void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage(context));
    
            var year = Attribute.Year.ToString(CultureInfo.InvariantCulture);
            MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
        }
    
        public override string GetErrorMessage(ModelValidationContextBase validationContext)
            => Attribute.GetErrorMessage();
    }
    
  2. uygulayan IValidationAttributeAdapterProviderbir bağdaştırıcı sağlayıcı sınıfı oluşturun. GetAttributeAdapter yönteminde, bu örnekte gösterildiği gibi bağdaştırıcının oluşturucusunun özel özniteliğini geçirin:

    public class CustomValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider
    {
        private readonly IValidationAttributeAdapterProvider baseProvider =
            new ValidationAttributeAdapterProvider();
    
        public IAttributeAdapter? GetAttributeAdapter(
            ValidationAttribute attribute, IStringLocalizer? stringLocalizer)
        {
            if (attribute is ClassicMovieAttribute classicMovieAttribute)
            {
                return new ClassicMovieAttributeAdapter(classicMovieAttribute, stringLocalizer);
            }
    
            return baseProvider.GetAttributeAdapter(attribute, stringLocalizer);
        }
    }
    
  3. içinde DI için bağdaştırıcı sağlayıcısını Program.cskaydedin:

    builder.Services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.MaxModelValidationErrors = 50;
            options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
                _ => "The field is required.");
        });
    
    builder.Services.AddSingleton
        <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
    

İstemci tarafı doğrulaması için IClientModelValidator

HTML'de öznitelikleri işlemenin data- bu yöntemi, örnek uygulamadaki özniteliği tarafından ClassicMovieWithClientValidator kullanılır. Bu yöntemi kullanarak istemci doğrulaması eklemek için:

  • Özel doğrulama özniteliğinde arabirimini IClientModelValidator uygulayın ve bir AddValidation yöntem oluşturun. yönteminde AddValidation , aşağıdaki örnekte gösterildiği gibi doğrulama öznitelikleri ekleyin data- :

    public class ClassicMovieWithClientValidatorAttribute :
        ValidationAttribute, IClientModelValidator
    {
        public ClassicMovieWithClientValidatorAttribute(int year)
            => Year = year;
    
        public int Year { get; }
    
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage());
    
            var year = Year.ToString(CultureInfo.InvariantCulture);
            MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
        }
    
        public string GetErrorMessage() =>
            $"Classic movies must have a release year no later than {Year}.";
    
        protected override ValidationResult? IsValid(
            object? value, ValidationContext validationContext)
        {
            var movie = (Movie)validationContext.ObjectInstance;
            var releaseYear = ((DateTime)value!).Year;
    
            if (movie.Genre == Genre.Classic && releaseYear > Year)
            {
                return new ValidationResult(GetErrorMessage());
            }
    
            return ValidationResult.Success;
        }
    
        private static bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
    
            attributes.Add(key, value);
            return true;
        }
    }
    

İstemci tarafı doğrulamayı devre dışı bırakma

Aşağıdaki kod, Sayfalar'da Razor istemci doğrulamasını devre dışı bırakır:

builder.Services.AddRazorPages()
    .AddViewOptions(options =>
    {
        options.HtmlHelperOptions.ClientValidationEnabled = false;
    });

İstemci tarafı doğrulamasını devre dışı bırakmak için diğer seçenekler:

  • Başvuruyu _ValidationScriptsPartial tüm dosyalarda açıklama satırı oluşturun .cshtml .
  • Pages\Shared_ValidationScriptsPartial.cshtml dosyasının içeriğini kaldırın.

Yukarıdaki yaklaşım, ASP.NET Core IdentityRazor sınıf kitaplığının istemci tarafı doğrulamasını engellemez. Daha fazla bilgi için bkz. ASP.NET Core projelerinde yapı iskelesiIdentity.

Ek kaynaklar

Bu makalede, ASP.NET Core MVC veya Razor Pages uygulamasında kullanıcı girişinin nasıl doğrulanması açıklanır.

Örnek kodu görüntüleme veya indirme (indirme).

Model durumu

Model durumu, iki alt sistemden gelen hataları temsil eder: model bağlama ve model doğrulama. Model bağlamasından kaynaklanan hatalar genellikle veri dönüştürme hatalarıdır. Örneğin, bir tamsayı alanına "x" girilir. Model doğrulama, model bağlamadan sonra gerçekleşir ve verilerin iş kurallarına uymadığı hataları bildirir. Örneğin, derecelendirmenin 1 ile 5 arasında olmasını bekleyen bir alana 0 girilir.

Hem model bağlama hem de model doğrulama, bir denetleyici eyleminin veya Razor Pages işleyici yönteminin yürütülmesinden önce gerçekleşir. Web uygulamaları için uygun şekilde incelemek ModelState.IsValid ve tepki vermek uygulamanın sorumluluğundadır. Web uygulamaları genellikle sayfayı bir hata iletisiyle yeniden görüntüler:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movies.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Web API denetleyicilerinin [ApiController] özniteliğine sahip olup olmadığını denetlemeleri ModelState.IsValid gerekmez. Bu durumda, model durumu geçersiz olduğunda hata ayrıntılarını içeren otomatik bir HTTP 400 yanıtı döndürülür. Daha fazla bilgi için bkz . Otomatik HTTP 400 yanıtları.

Doğrulamayı yeniden çalıştırma

Doğrulama otomatiktir, ancak el ile yinelemek isteyebilirsiniz. Örneğin, bir özellik için bir değer hesaplayabilirsiniz ve özelliği hesaplanan değere ayarladıktan sonra doğrulamayı yeniden çalıştırmak isteyebilirsiniz. Doğrulamayı yeniden çalıştırmak için, doğrulanan modele özgü doğrulamayı temizlemek için öğesini ve ardından TryValidateModelöğesini çağırınModelStateDictionary.ClearValidationState:

public async Task<IActionResult> OnPostTryValidateAsync()
{
    var modifiedReleaseDate = DateTime.Now.Date;
    Movie.ReleaseDate = modifiedReleaseDate;

    ModelState.ClearValidationState(nameof(Movie));
    if (!TryValidateModel(Movie, nameof(Movie)))
    {
        return Page();
    }

    _context.Movies.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

Doğrulama öznitelikleri

Doğrulama öznitelikleri, model özellikleri için doğrulama kuralları belirtmenize olanak sağlar. Örnek uygulamadan alınan aşağıdaki örnekte, doğrulama öznitelikleriyle açıklama eklenen bir model sınıfı gösterilmektedir. [ClassicMovie] özniteliği özel bir doğrulama özniteliğidir ve diğerleri yerleşiktir. gösterilmez, [ClassicMovieWithClientValidator]bu da özel bir öznitelik uygulamak için alternatif bir yol gösterir.

public class Movie
{
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; }

    [ClassicMovie(1960)]
    [DataType(DataType.Date)]
    [Display(Name = "Release Date")]
    public DateTime ReleaseDate { get; set; }

    [Required]
    [StringLength(1000)]
    public string Description { get; set; }

    [Range(0, 999.99)]
    public decimal Price { get; set; }

    public Genre Genre { get; set; }

    public bool Preorder { get; set; }
}

Yerleşik öznitelikler

Yerleşik doğrulama özniteliklerinden bazıları şunlardır:

  • [ValidateNever]: Bir özelliğin veya parametrenin doğrulamanın dışında tutulması gerektiğini gösterir.
  • [CreditCard]: Özelliğin kredi kartı biçiminde olduğunu doğrular. jQuery Doğrulama Ek Yöntemleri gerektirir.
  • [Karşılaştır]: Modeldeki iki özelliğin eşleştiklerini doğrular.
  • [EmailAddress]: Özelliğin e-posta biçimi olduğunu doğrular.
  • [Telefon]: Özelliğin telefon numarası biçimine sahip olduğunu doğrular.
  • [Aralık]: Özellik değerinin belirtilen aralık içinde olduğunu doğrular.
  • [RegularExpression]: Özellik değerinin belirtilen normal ifadeyle eşleştiklerini doğrular.
  • [Gerekli]: Alanın null olmadığını doğrular. Bu özniteliğin davranışıyla ilgili ayrıntılar için bkz [Required] . öznitelik .
  • [StringLength]: Dize özellik değerinin belirtilen uzunluk sınırını aşmadığını doğrular.
  • [Url]: Özelliğin BIR URL biçimi olduğunu doğrular.
  • [Uzak]: Sunucuda bir eylem yöntemi çağırarak istemcideki girişi doğrular. Bu özniteliğin davranışıyla ilgili ayrıntılar için bkz [Remote] . öznitelik .

Doğrulama özniteliklerinin tam listesi ad alanında System.ComponentModel.DataAnnotations bulunabilir.

Hata iletileri

Doğrulama öznitelikleri, geçersiz giriş için görüntülenecek hata iletisini belirtmenize olanak sağlar. Örneğin:

[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]

Öznitelikler dahili olarak, alan adı ve bazen ek yer tutucular için bir yer tutucu ile çağrır String.Format . Örneğin:

[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]

Bir Name özelliğe uygulandığında, önceki kod tarafından oluşturulan hata iletisi "Ad uzunluğu 6 ile 8 arasında olmalıdır".

Belirli bir özniteliğin hata iletisi için hangi parametrelerin geçirildiğini String.Format öğrenmek için Bkz . DataAnnotations kaynak kodu.

Null değer atanamayan başvuru türleri ve [Gerekli] özniteliği

Doğrulama sistemi, null değer atanamayan parametreleri veya ilişkili özellikleri bir [Required(AllowEmptyStrings = true)] özniteliği varmış gibi ele alır. MVC, bağlamları etkinleştirerek Nullable , boş değer atanamayan özellikleri veya parametreleri özniteliğiyle ilişkilendirilmiş gibi örtük olarak doğrulamaya [Required(AllowEmptyStrings = true)] başlar. Aşağıdaki kodu inceleyin:

public class Person
{
    public string Name { get; set; }
}

Uygulama ile <Nullable>enable</Nullable>oluşturulduysa, JSON veya form gönderisinde için Name eksik bir değer doğrulama hatasıyla sonuçlanır. Özelliği için null veya eksik değerlerin belirtilmesine izin vermek için Name null atanabilir bir başvuru türü kullanın:

public class Person
{
    public string? Name { get; set; }
}

Bu davranış, içinde Startup.ConfigureServicesyapılandırılarak SuppressImplicitRequiredAttributeForNonNullableReferenceTypes devre dışı bırakılabilir:

services.AddControllers(options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);

Sunucuda [Gerekli] doğrulama

Sunucuda, özellik null olduğunda gerekli bir değerin eksik olduğu kabul edilir. Null değer atanamayan bir alan her zaman geçerlidir ve özniteliğin [Required] hata iletisi hiçbir zaman görüntülenmez.

Ancak, null değer atanamayan bir özellik için model bağlama başarısız olabilir ve gibi The value '' is invalidbir hata iletisiyle sonuçlanabilir. Null değer atanamayan türlerin sunucu tarafı doğrulaması için özel bir hata iletisi belirtmek için aşağıdaki seçeneklere sahipsiniz:

  • Alanı null atanabilir hale getirin (örneğin, decimal? yerine decimal). Null atanabilir<T> değer türleri standart null atanabilir türler olarak kabul edilir.

  • Aşağıdaki örnekte gösterildiği gibi model bağlaması tarafından kullanılacak varsayılan hata iletisini belirtin:

    services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.MaxModelValidationErrors = 50;
            options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
                _ => "The field is required.");
        });
    
    services.AddSingleton<IValidationAttributeAdapterProvider,
        CustomValidationAttributeAdapterProvider>();
    

    Varsayılan iletileri ayarlayabileceğiniz model bağlama hataları hakkında daha fazla bilgi için bkz DefaultModelBindingMessageProvider. .

İstemcide [Gerekli] doğrulama

Null değer atanamayan türler ve dizeler istemcide sunucuyla karşılaştırıldığında farklı şekilde işlenir. İstemcide:

  • Bir değerin mevcut olduğu kabul edilir, ancak bu değer için giriş girilirse. Bu nedenle, istemci tarafı doğrulama null atanamayan türleri null atanabilir türlerle aynı şekilde işler.
  • Dize alanındaki boşluk, jQuery Doğrulaması gerekli yöntemi tarafından geçerli giriş olarak kabul edilir. Sunucu tarafı doğrulaması, yalnızca boşluk girilirse gerekli dize alanını geçersiz sayıyor.

Daha önce belirtildiği gibi, null atanamayan türler bir [Required(AllowEmptyStrings = true)] özniteliği varmış gibi kabul edilir. Bu, özniteliğini uygulamasanız bile istemci tarafı doğrulamasını [Required(AllowEmptyStrings = true)] alabileceğiniz anlamına gelir. Ancak özniteliğini kullanmazsanız varsayılan bir hata iletisi alırsınız. Özel bir hata iletisi belirtmek için özniteliğini kullanın.

[Remote] özniteliği

[Remote] özniteliği, alan girişinin geçerli olup olmadığını belirlemek için sunucuda bir yöntem çağırmayı gerektiren istemci tarafı doğrulaması uygular. Örneğin, uygulamanın bir kullanıcı adının zaten kullanımda olup olmadığını doğrulaması gerekebilir.

Uzaktan doğrulama uygulamak için:

  1. JavaScript'in çağıracağı bir eylem yöntemi oluşturun. jQuery Doğrulama uzak yöntemi bir JSON yanıtı bekler:

    • true giriş verilerinin geçerli olduğu anlamına gelir.
    • false, undefinedveya null girişin geçersiz olduğu anlamına gelir. Varsayılan hata iletisini görüntüleyin.
    • Diğer dizeler girişin geçersiz olduğu anlamına gelir. Dizeyi özel bir hata iletisi olarak görüntüleyin.

    Aşağıda özel hata iletisi döndüren bir eylem yöntemi örneği verilmiştir:

    [AcceptVerbs("GET", "POST")]
    public IActionResult VerifyEmail(string email)
    {
        if (!_userService.VerifyEmail(email))
        {
            return Json($"Email {email} is already in use.");
        }
    
        return Json(true);
    }
    
  2. Model sınıfında, aşağıdaki örnekte gösterildiği gibi doğrulama eylemi yöntemine işaret eden bir [Remote] öznitelikle özelliğine açıklama ekleyin:

    [Remote(action: "VerifyEmail", controller: "Users")]
    public string Email { get; set; }
    

Ek alanlar

AdditionalFields özniteliğinin [Remote] özelliği, sunucudaki verilerde alan birleşimlerini doğrulamanıza olanak tanır. Örneğin, modelde User FirstName ve LastName özellikleri varsa, mevcut kullanıcıların bu ad çiftine sahip olmadığını doğrulamak isteyebilirsiniz. Aşağıdaki örnekte nasıl kullanılacağı gösterilmektedir AdditionalFields:

[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(LastName))]
[Display(Name = "First Name")]
public string FirstName { get; set; }

[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(FirstName))]
[Display(Name = "Last Name")]
public string LastName { get; set; }

AdditionalFieldsaçıkça "FirstName" ve "LastName" dizelerine ayarlanabilir, ancak nameof işlecinin kullanılması daha sonra yeniden düzenlemeyi kolaylaştırır. Bu doğrulama için eylem yöntemi hem hem de firstName lastName bağımsız değişkenlerini kabul etmelidir:

[AcceptVerbs("GET", "POST")]
public IActionResult VerifyName(string firstName, string lastName)
{
    if (!_userService.VerifyName(firstName, lastName))
    {
        return Json($"A user named {firstName} {lastName} already exists.");
    }

    return Json(true);
}

Kullanıcı bir ad veya soyadı girdiğinde, JavaScript bu ad çiftinin alınıp alınmadığını görmek için uzak bir çağrı yapar.

İki veya daha fazla ek alanı doğrulamak için, bunları virgülle ayrılmış liste olarak sağlayın. Örneğin, modele özellik MiddleName eklemek için özniteliğini [Remote] aşağıdaki örnekte gösterildiği gibi ayarlayın:

[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(FirstName) + "," + nameof(LastName))]
public string MiddleName { get; set; }

AdditionalFields, tüm öznitelik bağımsız değişkenleri gibi sabit bir ifade olmalıdır. Bu nedenle, başlatmak AdditionalFieldsiçin ilişkilendirilmiş bir dize veya çağrı Join kullanmayın.

Yerleşik özniteliklere alternatifler

Yerleşik öznitelikler tarafından sağlanmayan doğrulamaya ihtiyacınız varsa şunları yapabilirsiniz:

Özel öznitelikler

Yerleşik doğrulama özniteliklerinin işlemediğini senaryolar için özel doğrulama öznitelikleri oluşturabilirsiniz. öğesinden ValidationAttributedevralan bir sınıf oluşturun ve yöntemini geçersiz kılın IsValid .

IsValid yöntemi, doğrulanacak giriş olan value adlı bir nesneyi kabul eder. Aşırı yükleme, model bağlaması tarafından oluşturulan model örneği gibi ek bilgiler sağlayan bir ValidationContext nesneyi de kabul eder.

Aşağıdaki örnek, Klasik tarzdaki bir filmin yayın tarihinin belirtilen yıldan sonra olmadığını doğrular. Özniteliği [ClassicMovie] :

  • Yalnızca sunucuda çalıştırılır.
  • Klasik filmler için yayın tarihini doğrular:
public class ClassicMovieAttribute : ValidationAttribute
{
    public ClassicMovieAttribute(int year)
    {
        Year = year;
    }

    public int Year { get; }

    public string GetErrorMessage() =>
        $"Classic movies must have a release year no later than {Year}.";

    protected override ValidationResult IsValid(object value,
        ValidationContext validationContext)
    {
        var movie = (Movie)validationContext.ObjectInstance;
        var releaseYear = ((DateTime)value).Year;

        if (movie.Genre == Genre.Classic && releaseYear > Year)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }
}

movie Yukarıdaki örnekteki değişken, form gönderimindeki verileri içeren bir Movie nesneyi temsil eder. Doğrulama başarısız olduğunda, ValidationResult hata iletisi içeren bir döndürülür.

IValidatableObject

Yukarıdaki örnek yalnızca türlerle Movie çalışır. Sınıf düzeyi doğrulama için bir diğer seçenek de aşağıdaki örnekte gösterildiği gibi model sınıfında uygulamaktır IValidatableObject :

public class ValidatableMovie : IValidatableObject
{
    private const int _classicYear = 1960;

    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Title { get; set; }

    [DataType(DataType.Date)]
    [Display(Name = "Release Date")]
    public DateTime ReleaseDate { get; set; }

    [Required]
    [StringLength(1000)]
    public string Description { get; set; }

    [Range(0, 999.99)]
    public decimal Price { get; set; }

    public Genre Genre { get; set; }

    public bool Preorder { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Genre == Genre.Classic && ReleaseDate.Year > _classicYear)
        {
            yield return new ValidationResult(
                $"Classic movies must have a release year no later than {_classicYear}.",
                new[] { nameof(ReleaseDate) });
        }
    }
}

Üst düzey düğüm doğrulama

En üst düzey düğümler şunlardır:

  • İşlem parametreleri
  • Denetleyici özellikleri
  • Sayfa işleyicisi parametreleri
  • Sayfa modeli özellikleri

Modele bağlı üst düzey düğümler, model özelliklerini doğrulamaya ek olarak doğrulanır. Örnek uygulamadan aşağıdaki örnekte yöntemi, VerifyPhone eylem parametresini doğrulamak phone için öğesini RegularExpressionAttribute kullanır:

[AcceptVerbs("GET", "POST")]
public IActionResult VerifyPhone(
    [RegularExpression(@"^\d{3}-\d{3}-\d{4}$")] string phone)
{
    if (!ModelState.IsValid)
    {
        return Json($"Phone {phone} has an invalid format. Format: ###-###-####");
    }

    return Json(true);
}

Üst düzey düğümler doğrulama öznitelikleriyle kullanabilir BindRequiredAttribute . Örnek uygulamadan alınan aşağıdaki örnekte yöntemi, CheckAge form gönderildiğinde parametrenin age sorgu dizesinden bağlanması gerektiğini belirtir:

[HttpPost]
public IActionResult CheckAge([BindRequired, FromQuery] int age)
{

Yaşı Denetle sayfasında ()CheckAge.cshtml iki form vardır. İlk form değerini Age 99 sorgu dizesi parametresi olarak gönderir: https://localhost:5001/Users/CheckAge?Age=99.

Sorgu dizesinden düzgün biçimlendirilmiş age bir parametre gönderildiğinde, form doğrulanır.

Yaşı Denetle sayfasındaki ikinci form, isteğin Age gövdesindeki değeri gönderir ve doğrulama başarısız olur. Parametrenin bir sorgu dizesinden gelmesi gerektiğinden age bağlama başarısız oluyor.

En fazla hata sayısı

Maksimum hata sayısına (varsayılan olarak 200) ulaşıldığında doğrulama durdurulur. Bu sayıyı içinde Startup.ConfigureServicesaşağıdaki kodla yapılandırabilirsiniz:

services.AddRazorPages()
    .AddMvcOptions(options =>
    {
        options.MaxModelValidationErrors = 50;
        options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
            _ => "The field is required.");
    });

services.AddSingleton<IValidationAttributeAdapterProvider,
    CustomValidationAttributeAdapterProvider>();

En fazla özyineleme

ValidationVisitor doğrulanan modelin nesne grafını gezer. Derin veya sonsuz özyinelemeli modeller için doğrulama, yığın taşmasına neden olabilir. MvcOptions.MaxValidationDepth , ziyaretçi özyinelemesi yapılandırılmış bir derinliği aşarsa doğrulamayı erken durdurmanın bir yolunu sağlar. varsayılan değeri MvcOptions.MaxValidationDepth 32'dir.

Otomatik kısa devre

Model grafı doğrulama gerektirmiyorsa doğrulama otomatik olarak kısa devreli (atlanır) olur. Çalışma zamanının doğrulamayı atlayan nesneleri, temel öğe koleksiyonlarını (, byte[]string[], Dictionary<string, string>gibi) ve herhangi bir doğrulayıcı içermeyen karmaşık nesne graflarını içerir.

İstemci tarafı doğrulama

İstemci tarafı doğrulama, form geçerli olana kadar gönderimi engeller. Gönder düğmesi formu gönderen veya hata iletileri görüntüleyen JavaScript'i çalıştırır.

İstemci tarafı doğrulama, formda giriş hataları olduğunda sunucuya gereksiz bir gidiş dönüşten kaçınıyor. aşağıdaki betik başvuruları ve _Layout.cshtml _ValidationScriptsPartial.cshtml istemci tarafı doğrulamasını destekler:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.js"></script>

jQuery Göze Çarpmayan Doğrulama betiği, popüler jQuery Doğrulama eklentisini kullanan özel bir Microsoft ön uç kitaplığıdır. jQuery Göze Çarpmayan Doğrulama olmadan aynı doğrulama mantığını iki yerde kodlasanız: model özelliklerindeki sunucu tarafı doğrulama özniteliklerine ve ardından istemci tarafı betiklerine bir kez daha. Bunun yerine, Etiket Yardımcıları ve HTML yardımcıları doğrulama gerektiren form öğeleri için HTML 5 data- özniteliklerini işlemek üzere doğrulama özniteliklerini kullanır ve model özelliklerinden meta verileri yazar. jQuery Göze Çarpmayan Doğrulama, öznitelikleri ayrıştırarak data- mantığı jQuery Doğrulaması'na geçirir ve sunucu tarafı doğrulama mantığını istemciye etkili bir şekilde "kopyalar". Burada gösterildiği gibi etiket yardımcılarını kullanarak istemcide doğrulama hataları görüntüleyebilirsiniz:

<div class="form-group">
    <label asp-for="Movie.ReleaseDate" class="control-label"></label>
    <input asp-for="Movie.ReleaseDate" class="form-control" />
    <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
</div>

Yukarıdaki etiket yardımcıları aşağıdaki HTML'yi işler:

<div class="form-group">
    <label class="control-label" for="Movie_ReleaseDate">Release Date</label>
    <input class="form-control" type="date" data-val="true"
        data-val-required="The Release Date field is required."
        id="Movie_ReleaseDate" name="Movie.ReleaseDate" value="">
    <span class="text-danger field-validation-valid"
        data-valmsg-for="Movie.ReleaseDate" data-valmsg-replace="true"></span>
</div>

HTML çıkışındaki data- özniteliklerin özelliği için doğrulama özniteliklerine Movie.ReleaseDate karşılık geldiğini fark edin. Özniteliği, data-val-required kullanıcı yayın tarihi alanını doldurmazsa görüntülenecek bir hata iletisi içerir. jQuery Göze Çarpmayan Doğrulama bu değeri jQuery Validation required() yöntemine geçirir ve bu yöntem bu iletiyi eşlik eden <span> öğesinde görüntüler.

Veri türü doğrulaması, [DataType] özniteliği tarafından geçersiz kılınmadığı sürece bir özelliğin .NET türünü temel alır. Tarayıcıların kendi varsayılan hata iletileri vardır, ancak jQuery Doğrulama Engelleyici Olmayan Doğrulama paketi bu iletileri geçersiz kılabilir. [DataType]öznitelikleri ve [EmailAddress] gibi alt sınıflar hata iletisini belirtmenize olanak sağlar.

Göze çarpmayan doğrulama

Engelleyici olmayan doğrulama hakkında bilgi için bu GitHub sorununa bakın.

Dinamik Formlara Doğrulama Ekleme

jQuery Göze Çarpmayan Doğrulama, sayfa ilk yüklendiğinde doğrulama mantığını ve parametrelerini jQuery Doğrulaması'na geçirir. Bu nedenle doğrulama, dinamik olarak oluşturulan formlarda otomatik olarak çalışmaz. Doğrulamayı etkinleştirmek için jQuery Engelleyici Olmayan Doğrulama'ya dinamik formu oluşturduktan hemen sonra ayrıştırmasını söyleyin. Örneğin, aşağıdaki kod AJAX aracılığıyla eklenen bir formda istemci tarafı doğrulamayı ayarlar.

$.get({
    url: "https://url/that/returns/a/form",
    dataType: "html",
    error: function(jqXHR, textStatus, errorThrown) {
        alert(textStatus + ": Couldn't add form. " + errorThrown);
    },
    success: function(newFormHTML) {
        var container = document.getElementById("form-container");
        container.insertAdjacentHTML("beforeend", newFormHTML);
        var forms = container.getElementsByTagName("form");
        var newForm = forms[forms.length - 1];
        $.validator.unobtrusive.parse(newForm);
    }
})

yöntemi, $.validator.unobtrusive.parse() tek bağımsız değişkeni için bir jQuery seçicisi kabul eder. Bu yöntem jQuery Unobtrusive Validation'a bu seçici içindeki data- formların özniteliklerini ayrıştırmalarını söyler. Daha sonra bu özniteliklerin değerleri jQuery Doğrulama eklentisine geçirilir.

Dinamik Denetimlere Doğrulama Ekleme

$.validator.unobtrusive.parse() yöntemi, ve <select/>gibi <input> dinamik olarak oluşturulan tek tek denetimlerde değil, formun tamamında çalışır. Formu yeniden ayrıştırmak için, aşağıdaki örnekte gösterildiği gibi, form daha önce ayrıştırıldığında eklenen doğrulama verilerini kaldırın:

$.get({
    url: "https://url/that/returns/a/control",
    dataType: "html",
    error: function(jqXHR, textStatus, errorThrown) {
        alert(textStatus + ": Couldn't add control. " + errorThrown);
    },
    success: function(newInputHTML) {
        var form = document.getElementById("my-form");
        form.insertAdjacentHTML("beforeend", newInputHTML);
        $(form).removeData("validator")    // Added by jQuery Validation
               .removeData("unobtrusiveValidation");   // Added by jQuery Unobtrusive Validation
        $.validator.unobtrusive.parse(form);
    }
})

Özel istemci tarafı doğrulama

Özel istemci tarafı doğrulama, özel bir jQuery Doğrulama bağdaştırıcısıyla çalışan HTML öznitelikleri oluşturularak data- yapılır. Bu makalenin [ClassicMovie] önceki bölümlerinde tanıtılan ve [ClassicMovieWithClientValidator] öznitelikleri için aşağıdaki örnek bağdaştırıcı kodu yazılmıştır:

$.validator.addMethod('classicmovie', function (value, element, params) {
    var genre = $(params[0]).val(), year = params[1], date = new Date(value);

    // The Classic genre has a value of '0'.
    if (genre && genre.length > 0 && genre[0] === '0') {
        // The release date for a Classic is valid if it's no greater than the given year.
        return date.getUTCFullYear() <= year;
    }

    return true;
});

$.validator.unobtrusive.adapters.add('classicmovie', ['year'], function (options) {
    var element = $(options.form).find('select#Movie_Genre')[0];

    options.rules['classicmovie'] = [element, parseInt(options.params['year'])];
    options.messages['classicmovie'] = options.message;
});

Bağdaştırıcı yazma hakkında bilgi için bkz . jQuery Doğrulama belgeleri.

Belirli bir alan için bağdaştırıcı kullanımı şu öznitelikler tarafından data- tetikleniyor:

  • Alana doğrulamaya (data-val="true") tabi olarak bayrak ekleyin.
  • Doğrulama kuralı adını ve hata iletisi metnini (örneğin, data-val-rulename="Error message.") tanımlayın.
  • Doğrulayıcının ihtiyaç duyduğu ek parametreleri sağlayın (örneğin, data-val-rulename-param1="value").

Aşağıdaki örnekte örnek uygulamanın özniteliğinin öznitelikleri gösterilmektedir data- ClassicMovie:

<input class="form-control" type="date"
    data-val="true"
    data-val-classicmovie="Classic movies must have a release year no later than 1960."
    data-val-classicmovie-year="1960"
    data-val-required="The Release Date field is required."
    id="Movie_ReleaseDate" name="Movie.ReleaseDate" value="">

Daha önce belirtildiği gibi, Etiket Yardımcıları ve HTML yardımcıları öznitelikleri işlemek data- için doğrulama özniteliklerinden bilgileri kullanır. Kod yazmak için özel data- HTML özniteliklerinin oluşturulmasına neden olan iki seçenek vardır:

  • öğesinden AttributeAdapterBase<TAttribute> türetilen ve öğesini uygulayan IValidationAttributeAdapterProviderbir sınıf oluşturun ve özniteliğinizi ve bağdaştırıcısını DI'ye kaydedin. Bu yöntem, sunucuyla ilgili ve istemciyle ilgili doğrulama kodunun ayrı sınıflarda yer alan tek sorumluluk ilkesini izler. Bağdaştırıcı, DI'ye kayıtlı olduğundan, gerekirse DI'deki diğer hizmetlerin de kullanılabilir olması avantajına da sahiptir.
  • Sınıfınızda ValidationAttribute uygulayınIClientModelValidator. Bu yöntem, özniteliği sunucu tarafı doğrulaması yapmıyorsa ve DI'den herhangi bir hizmete ihtiyaç duymadığında uygun olabilir.

İstemci tarafı doğrulaması için AttributeAdapter

HTML'de öznitelikleri işlemenin data- bu yöntemi, örnek uygulamadaki özniteliği tarafından ClassicMovie kullanılır. Bu yöntemi kullanarak istemci doğrulaması eklemek için:

  1. Özel doğrulama özniteliği için bir öznitelik bağdaştırıcısı sınıfı oluşturun. sınıfından türetilir AttributeAdapterBase<TAttribute>. Bu örnekte gösterildiği gibi işlenen çıkışa öznitelik ekleyen data- bir AddValidation yöntem oluşturun:

    public class ClassicMovieAttributeAdapter : AttributeAdapterBase<ClassicMovieAttribute>
    {
        public ClassicMovieAttributeAdapter(ClassicMovieAttribute attribute,
            IStringLocalizer stringLocalizer)
            : base(attribute, stringLocalizer)
        {
    
        }
    
        public override void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage(context));
    
            var year = Attribute.Year.ToString(CultureInfo.InvariantCulture);
            MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
        }
    
        public override string GetErrorMessage(ModelValidationContextBase validationContext) =>
            Attribute.GetErrorMessage();
    }
    
  2. uygulayan IValidationAttributeAdapterProviderbir bağdaştırıcı sağlayıcı sınıfı oluşturun. GetAttributeAdapter yönteminde, bu örnekte gösterildiği gibi bağdaştırıcının oluşturucusunun özel özniteliğini geçirin:

    public class CustomValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider
    {
        private readonly IValidationAttributeAdapterProvider baseProvider =
            new ValidationAttributeAdapterProvider();
    
        public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute,
            IStringLocalizer stringLocalizer)
        {
            if (attribute is ClassicMovieAttribute classicMovieAttribute)
            {
                return new ClassicMovieAttributeAdapter(classicMovieAttribute, stringLocalizer);
            }
    
            return baseProvider.GetAttributeAdapter(attribute, stringLocalizer);
        }
    }
    
  3. içinde DI için bağdaştırıcı sağlayıcısını Startup.ConfigureServiceskaydedin:

    services.AddRazorPages()
        .AddMvcOptions(options =>
        {
            options.MaxModelValidationErrors = 50;
            options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
                _ => "The field is required.");
        });
    
    services.AddSingleton<IValidationAttributeAdapterProvider,
        CustomValidationAttributeAdapterProvider>();
    

İstemci tarafı doğrulaması için IClientModelValidator

HTML'de öznitelikleri işlemenin data- bu yöntemi, örnek uygulamadaki özniteliği tarafından ClassicMovieWithClientValidator kullanılır. Bu yöntemi kullanarak istemci doğrulaması eklemek için:

  • Özel doğrulama özniteliğinde arabirimini IClientModelValidator uygulayın ve bir AddValidation yöntem oluşturun. yönteminde AddValidation , aşağıdaki örnekte gösterildiği gibi doğrulama öznitelikleri ekleyin data- :

    public class ClassicMovieWithClientValidatorAttribute :
        ValidationAttribute, IClientModelValidator
    {
        public ClassicMovieWithClientValidatorAttribute(int year)
        {
            Year = year;
        }
    
        public int Year { get; }
    
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage());
    
            var year = Year.ToString(CultureInfo.InvariantCulture);
            MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
        }
    
        public string GetErrorMessage() =>
            $"Classic movies must have a release year no later than {Year}.";
    
        protected override ValidationResult IsValid(object value,
            ValidationContext validationContext)
        {
            var movie = (Movie)validationContext.ObjectInstance;
            var releaseYear = ((DateTime)value).Year;
    
            if (movie.Genre == Genre.Classic && releaseYear > Year)
            {
                return new ValidationResult(GetErrorMessage());
            }
    
            return ValidationResult.Success;
        }
    
        private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
    
            attributes.Add(key, value);
            return true;
        }
    }
    

İstemci tarafı doğrulamayı devre dışı bırakma

Aşağıdaki kod, Sayfalar'da Razor istemci doğrulamasını devre dışı bırakır:

services.AddRazorPages()
    .AddViewOptions(options =>
    {
        options.HtmlHelperOptions.ClientValidationEnabled = false;
    });

İstemci tarafı doğrulamasını devre dışı bırakmak için diğer seçenekler:

  • Başvuruyu _ValidationScriptsPartial tüm dosyalarda açıklama satırı oluşturun .cshtml .
  • Pages\Shared_ValidationScriptsPartial.cshtml dosyasının içeriğini kaldırın.

Yukarıdaki yaklaşım, ASP.NET Core IdentityRazor sınıf kitaplığının istemci tarafı doğrulamasını engellemez. Daha fazla bilgi için bkz. ASP.NET Core projelerinde yapı iskelesiIdentity.

Ek kaynaklar