Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a cikk bemutatja, hogyan érvényesítheti a felhasználói bemenetet egy ASP.NET Core MVC- vagy Razor Pages-alkalmazásban.
Mintakód megtekintése vagy letöltése (hogyan töltsük le).
Ellenőrzés a .NET 10-ben
A .NET 10-ben az egyesített érvényesítési API-k át lettek helyezve a Microsoft.Extensions.Validation NuGet-csomagba. Ez a módosítás az érvényesítési API-kat ASP.NET Core HTTP-forgatókönyveken kívül is elérhetővé teszi.
Az Microsoft.Extensions.Validation API-k használata:
Adja hozzá a következő csomaghivatkozást:
<PackageReference Include="Microsoft.Extensions.Validation" Version="10.0.0" />A funkció változatlan marad, de most explicit csomaghivatkozásra van szükség.
Érvényesítési szolgáltatások regisztrálása függőséginjektálással:
builder.Services.AddValidation();
Modell állapota
A modellállapot két alrendszer hibáit jelöli: a modellkötést és a modellérvényesítést. A modellkötésből származó hibák általában adatkonvertálási hibák. Egy "x" például egy egész számmezőbe van beírva. A modell érvényesítése a modellkötés után történik, és olyan hibákat jelez, amelyekben az adatok nem felelnek meg az üzleti szabályoknak. Például egy 0 értéket ad meg egy olyan mezőben, amely 1 és 5 közötti értékelést vár.
A modellkötés és a modell érvényesítése is egy vezérlőművelet vagy egy Razor Pages-kezelő metódus végrehajtása előtt történik. A webalkalmazások esetében az alkalmazás feladata, hogy megvizsgálja ModelState.IsValid, és megfelelően reagáljon. A webalkalmazások általában hibaüzenettel jelenítik meg a lapot, ahogyan az a következő Razor Pages-példában is látható:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movies.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
A vezérlőkkel és nézetekkel rendelkező ASP.NET Core MVC esetében az alábbi példa bemutatja, hogyan ellenőrizheti ModelState.IsValid a vezérlőműveleten belül:
public async Task<IActionResult> Create(Movie movie)
{
if (!ModelState.IsValid)
{
return View(movie);
}
_context.Movies.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
A webes API-vezérlőknek nem kell ellenőrizniük ModelState.IsValid , hogy rendelkeznek-e az [ApiController] attribútummal. Ebben az esetben a rendszer a hibaadatokat tartalmazó automatikus HTTP 400-választ adja vissza, ha a modell állapota érvénytelen. További információ: Automatikus HTTP 400-válaszok.
Újrafuttatás ellenőrzése
Az érvényesítés automatikus, de előfordulhat, hogy manuálisan szeretné megismételni. Előfordulhat például, hogy egy tulajdonság értékét számítja ki, és újra szeretné futtatni az ellenőrzést, miután a tulajdonságot a kiszámított értékre állítja. Az érvényesítés újrafuttatásához először hívja meg a modellre vonatkozó ellenőrzés törléséhez a ModelStateDictionary.ClearValidationState, majd ezt kövesse a TryValidateModel meghívásával.
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");
}
Érvényesítési attribútumok
Az érvényesítési attribútumokkal érvényesítési szabályokat adhat meg a modelltulajdonságokhoz. A mintaalkalmazás alábbi példája egy olyan modellosztályt mutat be, amely érvényesítési attribútumokkal van eljegyzve. Az [ClassicMovie] attribútum egy egyéni érvényesítési attribútum, a többi pedig beépített. Az [ClassicMovieWithClientValidator] nem jelenik meg, amely a testreszabott attribútum megvalósításának egy alternatív módját mutatja be.
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; }
}
Beépített attribútumok
Az érvényesítési attribútumok teljes listáját a System.ComponentModel.DataAnnotations névtérben találja.
Hibaüzenetek
Az érvényesítési attribútumokkal megadhatja az érvénytelen bemenethez megjelenítendő hibaüzenetet. Például:
[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]
Belsőleg az attribútumok meghívják a String.Format-t, használva a mezőnév helyőrzőjét, és néha további helyőrzőket is. Például:
[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]
Egy tulajdonságra Name alkalmazva az előző kód által létrehozott hibaüzenet a következő: "A névhossznak 6 és 8 között kell lennie".
Annak kiderítéséhez, hogy String.Format egy adott attribútum hibaüzenete mely paramétereknek lesz átadva, tekintse meg a DataAnnotations forráskódját.
JSON-tulajdonságnevek használata érvényesítési hibák esetén
Alapértelmezés szerint, amikor érvényesítési hiba történik, a modell érvényesítése létrehoz egy ModelStateDictionary-t a tulajdonságnévvel, mint hiba kulcs. Egyes alkalmazások, például az egyoldalas alkalmazások, JSON-tulajdonságneveket használhatnak a webes API-kból generált érvényesítési hibákhoz. Az alábbi kód úgy konfigurálja az ellenőrzést, hogy a SystemTextJsonValidationMetadataProvider JSON-tulajdonságneveket használja:
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();
Az alábbi kód konfigurálja az ellenőrzést úgy, hogy NewtonsoftJsonValidationMetadataProvider a JSON tulajdonság nevét használja, amikor Json.NET-et használ:
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();
Például a camel-casing használatára vonatkozó szabályzatra a GitHubon találnak példátProgram.cs.
Nem null értékű hivatkozástípusok és [Kötelező] attribútum
Az érvényesítési rendszer úgy kezeli a nem null értékű paramétereket vagy kötött tulajdonságokat, mintha attribútummal [Required(AllowEmptyStrings = true)] rendelkeznének.
A Nullable kontextusok engedélyezésével az MVC implicit módon megkezdi a nem-null értékű tulajdonságok vagy paraméterek érvényesítését, mintha rendelkeznének az [Required(AllowEmptyStrings = true)] attribútummal. Vegye figyelembe a következő kódot:
public class Person
{
public string Name { get; set; }
}
Ha az alkalmazás <Nullable>enable</Nullable> segítségével készült, akkor a Name számára hiányzó érték a JSON-fájlban vagy az űrlap-bejegyzésben érvényesítési hibát eredményez. Ez ellentmondásosnak tűnhet, mivel az [Required(AllowEmptyStrings = true)] attribútum hallgatólagos, de ez várható viselkedés, mivel az üres sztringek alapértelmezés szerint null értékűre lesznek konvertálva. Nullázható hivatkozástípust használva engedélyezheti a Name tulajdonság számára, hogy null vagy hiányzó értékek legyenek megadva.
public class Person
{
public string? Name { get; set; }
}
Ez a viselkedés letiltható a következő SuppressImplicitRequiredAttributeForNonNullableReferenceTypesbeállítássalProgram.cs:
builder.Services.AddControllers(
options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);
[Kötelező] érvényesítés a kiszolgálón
A kiszolgálón a szükséges érték hiányzik, ha a tulajdonság null értékű. A nem null értékű mezők mindig érvényesek, és az [Required] attribútum hibaüzenete soha nem jelenik meg.
A nem null értékű tulajdonság modellkötése azonban meghiúsulhat, ami hibaüzenetet eredményez, például The value '' is invalid: . Ha egyéni hibaüzenetet szeretne megadni a nem null értékű típusok kiszolgálóoldali érvényesítéséhez, a következő lehetőségek közül választhat:
Tegye a mezőt nullelláthatóvá (például
decimal?helyettdecimal). Nullázható<A T> értéktípusokat a rendszer standard null értékű típusokként kezeli.Adja meg a modellkötés által használandó alapértelmezett hibaüzenetet az alábbi példában látható módon:
builder.Services.AddRazorPages() .AddMvcOptions(options => { options.MaxModelValidationErrors = 50; options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor( _ => "The field is required."); }); builder.Services.AddSingleton <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();További információ a modellkötési hibákról, amelyekhez alapértelmezett üzeneteket állíthat be, lásd: DefaultModelBindingMessageProvider.
[Kötelező] ellenőrzés az ügyfélen
A nem null értékű típusok és sztringek eltérően vannak kezelve az ügyfélen a kiszolgálóhoz képest. Az ügyfél oldalán
- Egy érték csak akkor tekinthető jelennek, ha van bemenet megadva. Ezért az ügyféloldali ellenőrzés a nem null értékű típusokat ugyanúgy kezeli, mint a null értékű típusokat.
- A sztringmezőben lévő szóközt a jQuery Validation kötelező metódusa érvényes bemenetnek tekinti. A kiszolgálóoldali ellenőrzés érvénytelennek tekint egy kötelező sztringmezőt, ha csak a szóköz van beírva.
Ahogy korábban említettük, a nem null értékű típusok úgy lesznek kezelve, mintha attribútummal [Required(AllowEmptyStrings = true)] rendelkeznének. Ez azt jelenti, hogy akkor is megkapja az ügyféloldali ellenőrzést, ha nem alkalmazza az [Required(AllowEmptyStrings = true)] attribútumot. Ha azonban nem használja az attribútumot, egy alapértelmezett hibaüzenet jelenik meg. Egyéni hibaüzenet megadásához használja az attribútumot.
[Távoli] attribútum
A [Távoli] attribútum ügyféloldali ellenőrzést valósít meg, amelyhez egy metódus meghívása szükséges a kiszolgálón annak megállapításához, hogy a mezőbemenet érvényes-e. Előfordulhat például, hogy az alkalmazásnak ellenőriznie kell, hogy egy felhasználónév már használatban van-e.
Távoli érvényesítés megvalósítása:
Hozzon létre egy műveletmetódust a JavaScript hívásához. A jQuery Validation remote metódus JSON-választ vár:
-
trueazt jelenti, hogy a bemeneti adatok érvényesek. -
false,undefinedvagynullazt jelenti, hogy a bemenet érvénytelen. Az alapértelmezett hibaüzenet megjelenítése. - Bármely más sztring azt jelenti, hogy a bemenet érvénytelen. A karakterlánc egyéni hibaüzenetként történő megjelenítése.
Íme egy példa egy egyéni hibaüzenetet visszaadó műveletmetódusra:
[AcceptVerbs("GET", "POST")] public IActionResult VerifyEmail(string email) { if (!_userService.VerifyEmail(email)) { return Json($"Email {email} is already in use."); } return Json(true); }-
A modellosztályban jegyzetelje a tulajdonságot egy
[Remote]olyan attribútummal, amely az érvényesítési művelet metódusára mutat, ahogyan az alábbi példában látható:[Remote(action: "VerifyEmail", controller: "Users")] public string Email { get; set; } = null!;
A kiszolgálóoldali érvényesítést olyan ügyfelek esetében is végre kell hajtani, amelyek letiltották a JavaScript használatát.
További mezők
Az AdditionalFields attribútum tulajdonsága lehetővé teszi a [Remote] mezők kombinációjának ellenőrzését a kiszolgálón lévő adatokkal szemben. Ha például a User modell rendelkezik FirstName és LastName rendelkezik tulajdonságokkal, érdemes lehet ellenőrizni, hogy a meglévő felhasználók nem rendelkeznek-e már ilyen névpárokkal. Az alábbi példa a AdditionalFieldshasználatát mutatja be:
[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!;
AdditionalFields a "FirstName" és a "LastName" sztringek explicit módon beállíthatók, de a nameof operátor használata egyszerűsíti a későbbi refaktorálást. Az érvényesítés műveleti metódusának mind a firstName-t, mind a lastName-t el kell fogadnia.
[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);
}
Amikor a felhasználó vezeték- vagy utónevet ad meg, a JavaScript távoli hívást indít annak megtekintéséhez, hogy a névpár létrejött-e.
Két vagy több további mező érvényesítéséhez adja meg őket vesszővel tagolt listaként. Ha például egy tulajdonságot MiddleName szeretne hozzáadni a modellhez, állítsa be az [Remote] attribútumot az alábbi példában látható módon:
[Remote(action: "VerifyName", controller: "Users",
AdditionalFields = nameof(FirstName) + "," + nameof(LastName))]
public string MiddleName { get; set; }
AdditionalFields, mint minden attribútumargumentum, állandó kifejezésnek kell lennie. Ezért ne használjon interpolált sztringet vagy hívjon meg Join inicializáláshoz AdditionalFields.
A beépített attribútumok alternatívái
Ha nem a beépített attribútumok által biztosított ellenőrzésre van szüksége, a következőkre van szüksége:
Egyéni attribútumok
Olyan forgatókönyvek esetén, amelyeket a beépített érvényesítési attribútumok nem kezelnek, egyéni érvényesítési attribútumokat hozhat létre. Hozzon létre egy olyan osztályt, amely örököl a ValidationAttribute osztályból, és írja felül a IsValid metódust.
A IsValid metódus elfogad egy érték nevű objektumot, amely az érvényesítendő bemenet. A túlterhelés egy objektumot is elfogad ValidationContext , amely további információkat nyújt, például a modellkötés által létrehozott modellpéldányt.
Az alábbi példa ellenőrzi, hogy a klasszikus műfajban lévő filmek megjelenési dátuma nem későbbi-e, mint egy adott év. Az [ClassicMovie] attribútum:
- Csak a kiszolgálón fut.
- Klasszikus filmek esetén ellenőrzi a kiadás dátumának érvényességét:
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;
}
}
Az movie előző példában szereplő változó egy Movie objektumot jelöl, amely az űrlapbeküldésből származó adatokat tartalmazza. Ha az ellenőrzés sikertelen, a ValidationResult rendszer hibaüzenetet ad vissza.
IValidatableObject
Az előző példa csak típusokkal Movie működik. Az osztályszintű ellenőrzés másik lehetősége a modellosztályban való implementálás IValidatableObject , ahogyan az alábbi példában látható:
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) });
}
}
}
Egyéni érvényesítés
Az alábbi kód bemutatja, hogyan adhat hozzá modellhibát a modell vizsgálata után:
if (Contact.Name == Contact.ShortName)
{
ModelState.AddModelError("Contact.ShortName",
"Short name can't be the same as Name.");
}
Az alábbi kód implementálja az érvényesítési tesztet egy vezérlőben:
if (contact.Name == contact.ShortName)
{
ModelState.AddModelError(nameof(contact.ShortName),
"Short name can't be the same as Name.");
}
Az alábbi kód ellenőrzi, hogy a telefonszám és az e-mail egyedi-e:
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");
}
Az alábbi kód implementálja az érvényesítési tesztet egy vezérlőben:
[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);
}
Az egyedi telefonszámok vagy e-mailek ellenőrzése általában távoli ellenőrzéssel is elvégezhető.
ValidationResult
Vegye figyelembe a következő egyéni beállítást:ValidateNameAttribute
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;
}
}
Az alábbi kódban az egyéni [ValidateName] attribútum lesz alkalmazva:
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; }
}
Ha a modell tartalmaz zz, a rendszer egy újat ValidationResult ad vissza.
Felső szintű csomópont érvényesítés
A legfelső szintű csomópontok a következők:
- Műveleti paraméterek
- Vezérlő tulajdonságai
- Lapkezelő paraméterei
- Lapmodell tulajdonságai
A modellhez kötött legfelső szintű csomópontok érvényesítésre kerülnek a modelltulajdonságok érvényesítésén felül. A mintaalkalmazás alábbi példájában a VerifyPhone metódus a RegularExpressionAttribute felhasználásával érvényesíti a phone műveletparamétert.
[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);
}
A legfelső szintű csomópontok érvényesítési attribútumokkal használhatók BindRequiredAttribute . A mintaalkalmazás alábbi példájában a CheckAge metódus azt határozza meg, hogy a age paramétert a lekérdezési sztringhez kell kötni az űrlap elküldésekor:
[HttpPost]
public IActionResult CheckAge([BindRequired, FromQuery] int age)
{
A Kor ellenőrzése lapon (CheckAge.cshtml) két űrlap található. Az első űrlap egy lekérdezési sztringparaméterként az Age értéket küldi el: 99.
Ha a lekérdezési sztringből megfelelően formázott age paramétert küld el, az űrlap érvényesíti.
Az Életkor ellenőrzése lapon található második űrlap elküldi az Age értéket a kérelem törzsében, és az ellenőrzés sikertelen. A kötés meghiúsul, mert a age paraméternek egy lekérdezési sztringből kell származnia.
Hibák maximális száma
Az érvényesítés a hibák maximális számának elérésekor (alapértelmezés szerint 200) leáll. Ezt a számot a következő kóddal konfigurálhatja:Program.cs
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.MaxModelValidationErrors = 50;
options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
_ => "The field is required.");
});
builder.Services.AddSingleton
<IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
Maximális rekurzió
ValidationVisitor bejárja az érvényesítendő modell objektumgráfját. Azoknál a modelleknél, amelyek mélyek vagy végtelenül rekurzívek, az érvényesítés veremtúlcsorduláshoz vezethet.
MvcOptions.MaxValidationDepth lehetővé teszi az ellenőrzés korai leállítását, ha a látogató rekurziója meghaladja a beállított mélységet. Az alapértelmezett érték MvcOptions.MaxValidationDepth 32.
Automatikus rövidzárlat
Az ellenőrzést automatikusan rövidre zárjuk (kihagyjuk), ha a modellgráf nem igényel ellenőrzést. Azok az objektumok, amelyek esetében a futtatókörnyezet kihagyja az ellenőrzést, primitív gyűjteményeket (például byte[], string[], ) Dictionary<string, string>és olyan összetett objektumgráfokat tartalmaznak, amelyek nem rendelkeznek érvényesítőkkel.
Ügyféloldali ellenőrzés
Az ügyféloldali ellenőrzés megakadályozza a beküldést, amíg az űrlap érvényes nem lesz. A Küldés gomb javaScriptet futtat, amely elküldi az űrlapot, vagy hibaüzeneteket jelenít meg.
Az ügyféloldali érvényesítés elkerüli a kiszolgáló szükségtelen oda-vissza utazását, ha bemeneti hibák jelentkeznek egy űrlapon. Az ügyféloldali érvényesítést _Layout.cshtml_ValidationScriptsPartial.cshtml a következő szkripthivatkozások támogatják:
<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>
A jQuery Unobtrusive Validation szkript egy egyéni Microsoft előtér-kódtár, amely a népszerű jQuery Validation beépülő modulra épül. A jQuery Unobtrusive Validation nélkül ugyanazt az érvényesítési logikát két helyen kell kódolva lennie: egyszer a modelltulajdonságok kiszolgálóoldali érvényesítési attribútumaiban, majd ismét az ügyféloldali szkriptekben. Ehelyett a címkesegítők és a HTML-segítők az érvényesítési attribútumokat használják, és a modelltulajdonságok metaadatainak beírásával renderelik az érvényesítésre szoruló űrlapelemek HTML 5 data- attribútumait. A jQuery Unobtrusive Validation elemzi az data- attribútumokat, és átadja a logikát a jQuery Validationnek, és hatékonyan "másolja" a kiszolgálóoldali érvényesítési logikát az ügyfélre. Az ügyféloldalon érvényesítési hibákat jeleníthet meg az itt látható címkesegítők használatával:
<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>
Az előző címkesegítők a következő HTML-t jelenítik meg:
<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>
Figyelje meg, hogy a data- HTML-kimenet attribútumai megfelelnek a tulajdonság érvényesítési attribútumainak Movie.ReleaseDate . Az data-val-required attribútum egy hibaüzenetet tartalmaz, amely akkor jelenik meg, ha a felhasználó nem tölti ki a kiadási dátum mezőt. A jQuery Unobtrusive Validation ezt az értéket átadja a jQuery Validation required() metódusnak , amely ezután megjeleníti az üzenetet a kísérő <span> elemben.
Az adattípus-ellenőrzés egy tulajdonság .NET-típusán alapul, kivéve, ha egy [DataType] attribútum felülírja. A böngészők saját alapértelmezett hibaüzenetekkel rendelkeznek, de a jQuery Validation Unobtrusive Validation csomag felülírhatja ezeket az üzeneteket.
[DataType] attribútumok és alosztályok, például a [EmailAddress] lehetővé teszik a hibaüzenet megadását.
Nem feltűnő ellenőrzés
A nem zavaró ellenőrzéssel kapcsolatos információkért tekintse meg ezt a GitHub-problémát.
Érvényesítés hozzáadása dinamikus űrlapokhoz
JQuery Unobtrusive Validation átadja az érvényesítési logikát és paramétereket a jQuery Validationnek az oldal első betöltésekor. Ezért az ellenőrzés nem működik automatikusan a dinamikusan létrehozott űrlapokon. Az érvényesítés engedélyezéséhez kérje meg a jQuery Nem feltűnő érvényesítés parancsot, hogy közvetlenül a létrehozás után elemezni tudja a dinamikus űrlapot. Az alábbi kód például egy AJAX-en keresztül hozzáadott űrlapon állítja be az ügyféloldali ellenőrzést.
$.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);
}
})
A $.validator.unobtrusive.parse() metódus egy jQuery-választót fogad el egyetlen argumentumához. Ez a módszer utasítja a jQuery Unobtrusive Validationt arra, hogy elemezze a data- attribútumokat a választóban lévő űrlapokon. Az attribútumok értékei ezután átadódnak a jQuery Validation beépülő modulnak.
Ellenőrzés hozzáadása dinamikus vezérlőkhöz
A $.validator.unobtrusive.parse() metódus egy teljes űrlapon működik, nem pedig az egyes dinamikusan létrehozott vezérlőkön, mint például <input> és <select/>. Az űrlap újraelemzéséhez távolítsa el az űrlap korábbi elemzésekor hozzáadott érvényesítési adatokat az alábbi példában látható módon:
$.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);
}
})
Egyéni ügyféloldali ellenőrzés
Az egyéni ügyféloldali érvényesítés egy egyéni jQuery validation adapterrel működő HTML-attribútumok létrehozásával data- történik. A következő mintaadapter-kód a korábban ebben a cikkben bevezetett [ClassicMovie] és [ClassicMovieWithClientValidator] attribútumokhoz készült:
$.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;
});
Az adapterek írásával kapcsolatos információkért tekintse meg a jQuery Validation dokumentációját.
Az adapter használatát egy adott mezőhöz a következő attribútumok data- váltják ki:
- A mező megjelölése ellenőrzés tárgyát képezőként (
data-val="true"). - Azonosítsa az érvényesítési szabály nevét és a hibaüzenet szövegét (például
data-val-rulename="Error message."). - Adjon meg minden további paramétert, amelyekre az érvényesítőnek szüksége van (például
data-val-rulename-param1="value").
Az alábbi példa a data-mintaalkalmazás attribútumainak attribútumaitClassicMovie mutatja be:
<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="">
Ahogy korábban említettük, a címkesegítők és a HTML-segítők az érvényesítési attribútumokból származó információkat használják az attribútumok rendereléséhez data- . A kódírásnak két lehetősége van, amelyek egyéni data- HTML-attribútumok létrehozását eredményezik:
- Hozzon létre egy olyan osztályt, amely származik AttributeAdapterBase<TAttribute> , és egy olyan osztályt, amely megvalósítja IValidationAttributeAdapterProvider, és regisztrálja az attribútumot és annak adapterét a DI-ben. Ez a módszer az egyetlen felelősség elvét követi abban az esetben, ha a kiszolgálóhoz és az ügyfélhez kapcsolódó érvényesítési kód külön osztályokban van. Az adapternek az az előnye is, hogy mivel regisztrálva van a DI-ben, a DI más szolgáltatásai is elérhetők, ha szükséges.
- Implementálja IClientModelValidator az ValidationAttribute osztályban. Ez a módszer akkor lehet megfelelő, ha az attribútum nem végez kiszolgálóoldali ellenőrzést, és nincs szüksége a diától származó szolgáltatásokra.
Attribútumadapter ügyféloldali ellenőrzéshez
A HTML attribútumok megjelenítésének ezen módszerét a data- attribútum használja a ClassicMovie. Ügyfélérvényesítés hozzáadása ezzel a módszerrel:
Hozzon létre egy attribútumadapter-osztályt az egyéni érvényesítési attribútumhoz. Az osztály származtatása a következőből: AttributeAdapterBase<TAttribute>. Hozzon létre egy metódust
AddValidation, amely attribútumokatdata-ad hozzá a renderelt kimenethez az alábbi példában látható módon: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(); }Hozzon létre egy adapter szolgáltató osztályt, amely implementálja a IValidationAttributeAdapterProvider-t. GetAttributeAdapter A metódusban adja át az egyéni attribútumot az adapter konstruktorának, ahogyan az ebben a példában látható:
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); } }Regisztrálja a DI-hez tartozó adapterszolgáltatót a következő helyen
Program.cs:builder.Services.AddRazorPages() .AddMvcOptions(options => { options.MaxModelValidationErrors = 50; options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor( _ => "The field is required."); }); builder.Services.AddSingleton <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
IClientModelValidator ügyféloldali ellenőrzéshez
A HTML attribútumok megjelenítésének ezen módszerét a data- attribútum használja a ClassicMovieWithClientValidator. Ügyfélérvényesítés hozzáadása ezzel a módszerrel:
Az egyéni érvényesítési attribútumban implementálja az interfészt IClientModelValidator , és hozzon létre egy metódust AddValidation . A metódusban
AddValidationadjon hozzádata-attribútumokat az ellenőrzéshez, ahogyan az a következő példában látható: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; } }
Ügyféloldali érvényesítés letiltása
Az alábbi kód letiltja az ügyfélérvényesítést a Pagesben Razor :
builder.Services.AddRazorPages()
.AddViewOptions(options =>
{
options.HtmlHelperOptions.ClientValidationEnabled = false;
});
További lehetőségek az ügyféloldali érvényesítés letiltására:
- Az összes
_ValidationScriptsPartialfájlban kommenteljük ki a.cshtmlhivatkozást. - Távolítsa el a Pages\Shared_ValidationScriptsPartial.cshtml fájl tartalmát.
Az előző megközelítés nem akadályozza meg a ASP.NET Core IdentityRazor osztálykódtár ügyféloldali ellenőrzését. További információ: Állványzat Identity ASP.NET Core-projektekben.
Probléma részletei
A probléma részletei nem az egyetlen válaszformátum a HTTP API-hibák leírásához, azonban gyakran használják őket a HTTP API-k hibáinak jelentésére.
A probléma részletei szolgáltatás implementálja a felületet, amely támogatja a IProblemDetailsService probléma részleteinek létrehozását a ASP.NET Core-ban. A AddProblemDetails(IServiceCollection) bővítménymetódus a IServiceCollection regisztrálja az alapértelmezett IProblemDetailsService implementációt.
A ASP.NET Core-alkalmazásokban a következő köztes szoftver generálja a probléma részleteit HTTP-válaszok meghívásakorAddProblemDetails, kivéve, ha a Accept kérelem HTTP-fejléce nem tartalmazza a regisztrált IProblemDetailsWriter (alapértelmezett) által támogatott tartalomtípusokat: application/json
- ExceptionHandlerMiddleware: Probléma részleteit tartalmazó választ hoz létre, ha nincs definiálva egyéni kezelő.
- StatusCodePagesMiddleware: Alapértelmezés szerint létrehoz egy probléma részleteit tartalmazó választ.
-
DeveloperExceptionPageMiddleware: Probléma részleteit tartalmazó választ hoz létre a fejlesztési környezetben, amikor a kérelem HTTP-fejléce nem tartalmazza a
Acceptértéket.
További erőforrások
Ez a cikk bemutatja, hogyan érvényesítheti a felhasználói bemenetet egy ASP.NET Core MVC- vagy Razor Pages-alkalmazásban.
Mintakód megtekintése vagy letöltése (hogyan töltsük le).
Modell állapota
A modellállapot két alrendszer hibáit jelöli: a modellkötést és a modellérvényesítést. A modellkötésből származó hibák általában adatkonvertálási hibák. Egy "x" például egy egész számmezőbe van beírva. A modell érvényesítése a modellkötés után történik, és olyan hibákat jelez, amelyekben az adatok nem felelnek meg az üzleti szabályoknak. Például egy 0 értéket ad meg egy olyan mezőben, amely 1 és 5 közötti értékelést vár.
A modellkötés és a modell érvényesítése is egy vezérlőművelet vagy egy Razor Pages-kezelő metódus végrehajtása előtt történik. A webalkalmazások esetében az alkalmazás feladata, hogy megvizsgálja ModelState.IsValid, és megfelelően reagáljon. A webalkalmazások általában hibaüzenettel jelenítik meg a lapot, ahogyan az a következő Razor Pages-példában is látható:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movies.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
A vezérlőkkel és nézetekkel rendelkező ASP.NET Core MVC esetében az alábbi példa bemutatja, hogyan ellenőrizheti ModelState.IsValid a vezérlőműveleten belül:
public async Task<IActionResult> Create(Movie movie)
{
if (!ModelState.IsValid)
{
return View(movie);
}
_context.Movies.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
A webes API-vezérlőknek nem kell ellenőrizniük ModelState.IsValid , hogy rendelkeznek-e az [ApiController] attribútummal. Ebben az esetben a rendszer a hibaadatokat tartalmazó automatikus HTTP 400-választ adja vissza, ha a modell állapota érvénytelen. További információ: Automatikus HTTP 400-válaszok.
Újrafuttatás ellenőrzése
Az érvényesítés automatikus, de előfordulhat, hogy manuálisan szeretné megismételni. Előfordulhat például, hogy egy tulajdonság értékét számítja ki, és újra szeretné futtatni az ellenőrzést, miután a tulajdonságot a kiszámított értékre állítja. Az érvényesítés újrafuttatásához először hívja meg a modellre vonatkozó ellenőrzés törléséhez a ModelStateDictionary.ClearValidationState, majd ezt kövesse a TryValidateModel meghívásával.
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");
}
Érvényesítési attribútumok
Az érvényesítési attribútumokkal érvényesítési szabályokat adhat meg a modelltulajdonságokhoz. A mintaalkalmazás alábbi példája egy olyan modellosztályt mutat be, amely érvényesítési attribútumokkal van eljegyzve. Az [ClassicMovie] attribútum egy egyéni érvényesítési attribútum, a többi pedig beépített. Az [ClassicMovieWithClientValidator] nem jelenik meg, amely a testreszabott attribútum megvalósításának egy alternatív módját mutatja be.
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; }
}
Beépített attribútumok
Íme néhány beépített érvényesítési attribútum:
- [ValidateNever]: Azt jelzi, hogy egy tulajdonságot vagy paramétert ki kell zárni az ellenőrzésből.
- [CreditCard]: Ellenőrzi, hogy a tulajdonság rendelkezik-e hitelkártyaformátummal. További jQuery-érvényesítési módszereket igényel.
- [Összehasonlítás]: Ellenőrzi, hogy egy modell két tulajdonsága egyezik-e.
- [EmailAddress]: Ellenőrzi, hogy a tulajdonság e-mail formátumú-e.
- [Telefon]: Ellenőrzi, hogy a tulajdonság telefonszámformátummal rendelkezik-e.
- [Tartomány]: Ellenőrzi, hogy a tulajdonság értéke egy megadott tartományba esik-e.
- [RegularExpression]: Ellenőrzi, hogy a tulajdonság értéke megfelel-e egy megadott reguláris kifejezésnek.
-
[Kötelező]: Ellenőrzi, hogy a mező nem null értékű-e. Az attribútum működésének részleteiért tekintse meg
[Required]az attribútumot . - [StringLength]: Ellenőrzi, hogy egy sztringtulajdonság értéke nem lépi-e túl a megadott hosszkorlátot.
- [URL]: Ellenőrzi, hogy a tulajdonság URL-formátummal rendelkezik-e.
-
[Távoli]: Az ügyfél bemenetének ellenőrzése egy műveletmetódus meghívásával a kiszolgálón. Az attribútum működésének részleteiért tekintse meg
[Remote]az attribútumot .
Az érvényesítési attribútumok teljes listája megtalálható a System.ComponentModel.DataAnnotations névtérben.
Hibaüzenetek
Az érvényesítési attribútumokkal megadhatja az érvénytelen bemenethez megjelenítendő hibaüzenetet. Például:
[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]
Belsőleg az attribútumok meghívják a String.Format-t, használva a mezőnév helyőrzőjét, és néha további helyőrzőket is. Például:
[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]
Egy tulajdonságra Name alkalmazva az előző kód által létrehozott hibaüzenet a következő: "A névhossznak 6 és 8 között kell lennie".
Annak kiderítéséhez, hogy String.Format egy adott attribútum hibaüzenete mely paramétereknek lesz átadva, tekintse meg a DataAnnotations forráskódját.
Nem null értékű hivatkozástípusok és a [Kötelező] attribútum
Az érvényesítési rendszer úgy kezeli a nem null értékű paramétereket vagy kötött tulajdonságokat, mintha attribútummal [Required(AllowEmptyStrings = true)] rendelkeznének.
A környezetek engedélyezésével Nullableaz MVC implicit módon megkezdi a nem null értékű tulajdonságok érvényesítését a nem általános típusokon vagy paramétereken, mintha az [Required(AllowEmptyStrings = true)] attribútummal lettek volna társítva. Vegye figyelembe a következő kódot:
public class Person
{
public string Name { get; set; }
}
Ha az alkalmazás <Nullable>enable</Nullable> segítségével készült, akkor a Name számára hiányzó érték a JSON-fájlban vagy az űrlap-bejegyzésben érvényesítési hibát eredményez. Nullázható hivatkozástípust használva engedélyezheti a Name tulajdonság számára, hogy null vagy hiányzó értékek legyenek megadva.
public class Person
{
public string? Name { get; set; }
}
Ez a viselkedés letiltható a következő SuppressImplicitRequiredAttributeForNonNullableReferenceTypesbeállítássalProgram.cs:
builder.Services.AddControllers(
options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);
Nem null értékű tulajdonságok az általános típusokon és a [Kötelező] attribútumon
Az általános típusok nem null értékű tulajdonságainak tartalmazniuk kell az [Required] attribútumot, ha a típus szükséges. A következő kódban TestRequired nem szükséges:
public class WeatherForecast<T>
{
public string TestRequired { get; set; } = null!;
public T? Inner { get; set; }
}
A következő kódban TestRequired explicit módon kötelezőként van megjelölve.
using System.ComponentModel.DataAnnotations;
public class WeatherForecast<T>
{
[Required]
public string TestRequired { get; set; } = null!;
public T? Inner { get; set; }
}
[Kötelező] érvényesítés a kiszolgálón
A kiszolgálón a szükséges érték hiányzik, ha a tulajdonság null értékű. A nem null értékű mezők mindig érvényesek, és az [Required] attribútum hibaüzenete soha nem jelenik meg.
A nem null értékű tulajdonság modellkötése azonban meghiúsulhat, ami hibaüzenetet eredményez, például The value '' is invalid: . Ha egyéni hibaüzenetet szeretne megadni a nem null értékű típusok kiszolgálóoldali érvényesítéséhez, a következő lehetőségek közül választhat:
Tegye a mezőt nullelláthatóvá (például
decimal?helyettdecimal). Nullázható<A T> értéktípusokat a rendszer standard null értékű típusokként kezeli.Adja meg a modellkötés által használandó alapértelmezett hibaüzenetet az alábbi példában látható módon:
builder.Services.AddRazorPages() .AddMvcOptions(options => { options.MaxModelValidationErrors = 50; options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor( _ => "The field is required."); }); builder.Services.AddSingleton <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();További információ a modellkötési hibákról, amelyekhez alapértelmezett üzeneteket állíthat be, lásd: DefaultModelBindingMessageProvider.
[Kötelező] ellenőrzés az ügyfélen
A nem null értékű típusok és sztringek eltérően vannak kezelve az ügyfélen a kiszolgálóhoz képest. Az ügyfél oldalán
- Egy érték csak akkor tekinthető jelennek, ha van bemenet megadva. Ezért az ügyféloldali ellenőrzés a nem null értékű típusokat ugyanúgy kezeli, mint a null értékű típusokat.
- A sztringmezőben lévő szóközt a jQuery Validation kötelező metódusa érvényes bemenetnek tekinti. A kiszolgálóoldali ellenőrzés érvénytelennek tekint egy kötelező sztringmezőt, ha csak a szóköz van beírva.
Ahogy korábban említettük, a nem null értékű típusok úgy lesznek kezelve, mintha attribútummal [Required(AllowEmptyStrings = true)] rendelkeznének. Ez azt jelenti, hogy akkor is megkapja az ügyféloldali ellenőrzést, ha nem alkalmazza az [Required(AllowEmptyStrings = true)] attribútumot. Ha azonban nem használja az attribútumot, egy alapértelmezett hibaüzenet jelenik meg. Egyéni hibaüzenet megadásához használja az attribútumot.
[Távoli] attribútum
A [Távoli] attribútum ügyféloldali ellenőrzést valósít meg, amelyhez egy metódus meghívása szükséges a kiszolgálón annak megállapításához, hogy a mezőbemenet érvényes-e. Előfordulhat például, hogy az alkalmazásnak ellenőriznie kell, hogy egy felhasználónév már használatban van-e.
Távoli érvényesítés megvalósítása:
Hozzon létre egy műveletmetódust a JavaScript hívásához. A jQuery Validation remote metódus JSON-választ vár:
-
trueazt jelenti, hogy a bemeneti adatok érvényesek. -
false,undefinedvagynullazt jelenti, hogy a bemenet érvénytelen. Az alapértelmezett hibaüzenet megjelenítése. - Bármely más sztring azt jelenti, hogy a bemenet érvénytelen. A karakterlánc egyéni hibaüzenetként történő megjelenítése.
Íme egy példa egy egyéni hibaüzenetet visszaadó műveletmetódusra:
[AcceptVerbs("GET", "POST")] public IActionResult VerifyEmail(string email) { if (!_userService.VerifyEmail(email)) { return Json($"Email {email} is already in use."); } return Json(true); }-
A modellosztályban jegyzetelje a tulajdonságot egy
[Remote]olyan attribútummal, amely az érvényesítési művelet metódusára mutat, ahogyan az alábbi példában látható:[Remote(action: "VerifyEmail", controller: "Users")] public string Email { get; set; } = null!;
További mezők
Az AdditionalFields attribútum tulajdonsága lehetővé teszi a [Remote] mezők kombinációjának ellenőrzését a kiszolgálón lévő adatokkal szemben. Ha például a User modell rendelkezik FirstName és LastName rendelkezik tulajdonságokkal, érdemes lehet ellenőrizni, hogy a meglévő felhasználók nem rendelkeznek-e már ilyen névpárokkal. Az alábbi példa a AdditionalFieldshasználatát mutatja be:
[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!;
AdditionalFields a "FirstName" és a "LastName" sztringek explicit módon beállíthatók, de a nameof operátor használata egyszerűsíti a későbbi refaktorálást. Az érvényesítés műveleti metódusának mind a firstName-t, mind a lastName-t el kell fogadnia.
[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);
}
Amikor a felhasználó vezeték- vagy utónevet ad meg, a JavaScript távoli hívást indít annak megtekintéséhez, hogy a névpár létrejött-e.
Két vagy több további mező érvényesítéséhez adja meg őket vesszővel tagolt listaként. Ha például egy tulajdonságot MiddleName szeretne hozzáadni a modellhez, állítsa be az [Remote] attribútumot az alábbi példában látható módon:
[Remote(action: "VerifyName", controller: "Users",
AdditionalFields = nameof(FirstName) + "," + nameof(LastName))]
public string MiddleName { get; set; }
AdditionalFields, mint minden attribútumargumentum, állandó kifejezésnek kell lennie. Ezért ne használjon interpolált sztringet vagy hívjon meg Join inicializáláshoz AdditionalFields.
A beépített attribútumok alternatívái
Ha nem a beépített attribútumok által biztosított ellenőrzésre van szüksége, a következőkre van szüksége:
Egyéni attribútumok
Olyan forgatókönyvek esetén, amelyeket a beépített érvényesítési attribútumok nem kezelnek, egyéni érvényesítési attribútumokat hozhat létre. Hozzon létre egy olyan osztályt, amely örököl a ValidationAttribute osztályból, és írja felül a IsValid metódust.
A IsValid metódus elfogad egy érték nevű objektumot, amely az érvényesítendő bemenet. A túlterhelés egy objektumot is elfogad ValidationContext , amely további információkat nyújt, például a modellkötés által létrehozott modellpéldányt.
Az alábbi példa ellenőrzi, hogy a klasszikus műfajban lévő filmek megjelenési dátuma nem későbbi-e, mint egy adott év. Az [ClassicMovie] attribútum:
- Csak a kiszolgálón fut.
- Klasszikus filmek esetén ellenőrzi a kiadás dátumának érvényességét:
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;
}
}
Az movie előző példában szereplő változó egy Movie objektumot jelöl, amely az űrlapbeküldésből származó adatokat tartalmazza. Ha az ellenőrzés sikertelen, a ValidationResult rendszer hibaüzenetet ad vissza.
IValidatableObject
Az előző példa csak típusokkal Movie működik. Az osztályszintű ellenőrzés másik lehetősége a modellosztályban való implementálás IValidatableObject , ahogyan az alábbi példában látható:
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) });
}
}
}
Felső szintű csomópont érvényesítés
A legfelső szintű csomópontok a következők:
- Műveleti paraméterek
- Vezérlő tulajdonságai
- Lapkezelő paraméterei
- Lapmodell tulajdonságai
A modellhez kötött legfelső szintű csomópontok érvényesítésre kerülnek a modelltulajdonságok érvényesítésén felül. A mintaalkalmazás alábbi példájában a VerifyPhone metódus a RegularExpressionAttribute felhasználásával érvényesíti a phone műveletparamétert.
[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);
}
A legfelső szintű csomópontok érvényesítési attribútumokkal használhatók BindRequiredAttribute . A mintaalkalmazás alábbi példájában a CheckAge metódus azt határozza meg, hogy a age paramétert a lekérdezési sztringhez kell kötni az űrlap elküldésekor:
[HttpPost]
public IActionResult CheckAge([BindRequired, FromQuery] int age)
{
A Kor ellenőrzése lapon (CheckAge.cshtml) két űrlap található. Az első űrlap egy lekérdezési sztringparaméterként az Age értéket küldi el: 99.
Ha a lekérdezési sztringből megfelelően formázott age paramétert küld el, az űrlap érvényesíti.
Az Életkor ellenőrzése lapon található második űrlap elküldi az Age értéket a kérelem törzsében, és az ellenőrzés sikertelen. A kötés meghiúsul, mert a age paraméternek egy lekérdezési sztringből kell származnia.
Hibák maximális száma
Az érvényesítés a hibák maximális számának elérésekor (alapértelmezés szerint 200) leáll. Ezt a számot a következő kóddal konfigurálhatja:Program.cs
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
options.MaxModelValidationErrors = 50;
options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
_ => "The field is required.");
});
builder.Services.AddSingleton
<IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
Maximális rekurzió
ValidationVisitor bejárja az érvényesítendő modell objektumgráfját. Azoknál a modelleknél, amelyek mélyek vagy végtelenül rekurzívek, az érvényesítés veremtúlcsorduláshoz vezethet.
MvcOptions.MaxValidationDepth lehetővé teszi az ellenőrzés korai leállítását, ha a látogató rekurziója meghaladja a beállított mélységet. Az alapértelmezett érték MvcOptions.MaxValidationDepth 32.
Automatikus rövidzárlat
Az ellenőrzést automatikusan rövidre zárjuk (kihagyjuk), ha a modellgráf nem igényel ellenőrzést. Azok az objektumok, amelyek esetében a futtatókörnyezet kihagyja az ellenőrzést, primitív gyűjteményeket (például byte[], string[], ) Dictionary<string, string>és olyan összetett objektumgráfokat tartalmaznak, amelyek nem rendelkeznek érvényesítőkkel.
Ügyféloldali ellenőrzés
Az ügyféloldali ellenőrzés megakadályozza a beküldést, amíg az űrlap érvényes nem lesz. A Küldés gomb javaScriptet futtat, amely elküldi az űrlapot, vagy hibaüzeneteket jelenít meg.
Az ügyféloldali érvényesítés elkerüli a kiszolgáló szükségtelen oda-vissza utazását, ha bemeneti hibák jelentkeznek egy űrlapon. Az ügyféloldali érvényesítést _Layout.cshtml_ValidationScriptsPartial.cshtml a következő szkripthivatkozások támogatják:
<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>
A jQuery Unobtrusive Validation szkript egy egyéni Microsoft előtér-kódtár, amely a népszerű jQuery Validation beépülő modulra épül. A jQuery Unobtrusive Validation nélkül ugyanazt az érvényesítési logikát két helyen kell kódolva lennie: egyszer a modelltulajdonságok kiszolgálóoldali érvényesítési attribútumaiban, majd ismét az ügyféloldali szkriptekben. Ehelyett a címkesegítők és a HTML-segítők az érvényesítési attribútumokat használják, és a modelltulajdonságok metaadatainak beírásával renderelik az érvényesítésre szoruló űrlapelemek HTML 5 data- attribútumait. A jQuery Unobtrusive Validation elemzi az data- attribútumokat, és átadja a logikát a jQuery Validationnek, és hatékonyan "másolja" a kiszolgálóoldali érvényesítési logikát az ügyfélre. Az ügyféloldalon érvényesítési hibákat jeleníthet meg az itt látható címkesegítők használatával:
<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>
Az előző címkesegítők a következő HTML-t jelenítik meg:
<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>
Figyelje meg, hogy a data- HTML-kimenet attribútumai megfelelnek a tulajdonság érvényesítési attribútumainak Movie.ReleaseDate . Az data-val-required attribútum egy hibaüzenetet tartalmaz, amely akkor jelenik meg, ha a felhasználó nem tölti ki a kiadási dátum mezőt. A jQuery Unobtrusive Validation ezt az értéket átadja a jQuery Validation required() metódusnak , amely ezután megjeleníti az üzenetet a kísérő <span> elemben.
Az adattípus-ellenőrzés egy tulajdonság .NET-típusán alapul, kivéve, ha egy [DataType] attribútum felülírja. A böngészők saját alapértelmezett hibaüzenetekkel rendelkeznek, de a jQuery Validation Unobtrusive Validation csomag felülírhatja ezeket az üzeneteket.
[DataType] attribútumok és alosztályok, például a [EmailAddress] lehetővé teszik a hibaüzenet megadását.
Nem feltűnő ellenőrzés
A nem zavaró ellenőrzéssel kapcsolatos információkért tekintse meg ezt a GitHub-problémát.
Érvényesítés hozzáadása dinamikus űrlapokhoz
JQuery Unobtrusive Validation átadja az érvényesítési logikát és paramétereket a jQuery Validationnek az oldal első betöltésekor. Ezért az ellenőrzés nem működik automatikusan a dinamikusan létrehozott űrlapokon. Az érvényesítés engedélyezéséhez kérje meg a jQuery Nem feltűnő érvényesítés parancsot, hogy közvetlenül a létrehozás után elemezni tudja a dinamikus űrlapot. Az alábbi kód például egy AJAX-en keresztül hozzáadott űrlapon állítja be az ügyféloldali ellenőrzést.
$.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);
}
})
A $.validator.unobtrusive.parse() metódus egy jQuery-választót fogad el egyetlen argumentumához. Ez a módszer utasítja a jQuery Unobtrusive Validationt arra, hogy elemezze a data- attribútumokat a választóban lévő űrlapokon. Az attribútumok értékei ezután átadódnak a jQuery Validation beépülő modulnak.
Ellenőrzés hozzáadása dinamikus vezérlőkhöz
A $.validator.unobtrusive.parse() metódus egy teljes űrlapon működik, nem pedig az egyes dinamikusan létrehozott vezérlőkön, mint például <input> és <select/>. Az űrlap újraelemzéséhez távolítsa el az űrlap korábbi elemzésekor hozzáadott érvényesítési adatokat az alábbi példában látható módon:
$.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);
}
})
Egyéni ügyféloldali ellenőrzés
Az egyéni ügyféloldali érvényesítés egy egyéni jQuery validation adapterrel működő HTML-attribútumok létrehozásával data- történik. A következő mintaadapter-kód a korábban ebben a cikkben bevezetett [ClassicMovie] és [ClassicMovieWithClientValidator] attribútumokhoz készült:
$.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;
});
Az adapterek írásával kapcsolatos információkért tekintse meg a jQuery Validation dokumentációját.
Az adapter használatát egy adott mezőhöz a következő attribútumok data- váltják ki:
- A mező megjelölése ellenőrzés tárgyát képezőként (
data-val="true"). - Azonosítsa az érvényesítési szabály nevét és a hibaüzenet szövegét (például
data-val-rulename="Error message."). - Adjon meg minden további paramétert, amelyekre az érvényesítőnek szüksége van (például
data-val-rulename-param1="value").
Az alábbi példa a data-mintaalkalmazás attribútumainak attribútumaitClassicMovie mutatja be:
<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="">
Ahogy korábban említettük, a címkesegítők és a HTML-segítők az érvényesítési attribútumokból származó információkat használják az attribútumok rendereléséhez data- . A kódírásnak két lehetősége van, amelyek egyéni data- HTML-attribútumok létrehozását eredményezik:
- Hozzon létre egy olyan osztályt, amely származik AttributeAdapterBase<TAttribute> , és egy olyan osztályt, amely megvalósítja IValidationAttributeAdapterProvider, és regisztrálja az attribútumot és annak adapterét a DI-ben. Ez a módszer az egyetlen felelősség elvét követi abban az esetben, ha a kiszolgálóhoz és az ügyfélhez kapcsolódó érvényesítési kód külön osztályokban van. Az adapternek az az előnye is, hogy mivel regisztrálva van a DI-ben, a DI más szolgáltatásai is elérhetők, ha szükséges.
- Implementálja IClientModelValidator az ValidationAttribute osztályban. Ez a módszer akkor lehet megfelelő, ha az attribútum nem végez kiszolgálóoldali ellenőrzést, és nincs szüksége a diától származó szolgáltatásokra.
Attribútumadapter ügyféloldali ellenőrzéshez
A HTML attribútumok megjelenítésének ezen módszerét a data- attribútum használja a ClassicMovie. Ügyfélérvényesítés hozzáadása ezzel a módszerrel:
Hozzon létre egy attribútumadapter-osztályt az egyéni érvényesítési attribútumhoz. Az osztály származtatása a következőből: AttributeAdapterBase<TAttribute>. Hozzon létre egy metódust
AddValidation, amely attribútumokatdata-ad hozzá a renderelt kimenethez az alábbi példában látható módon: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(); }Hozzon létre egy adapter szolgáltató osztályt, amely implementálja a IValidationAttributeAdapterProvider-t. GetAttributeAdapter A metódusban adja át az egyéni attribútumot az adapter konstruktorának, ahogyan az ebben a példában látható:
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); } }Regisztrálja a DI-hez tartozó adapterszolgáltatót a következő helyen
Program.cs:builder.Services.AddRazorPages() .AddMvcOptions(options => { options.MaxModelValidationErrors = 50; options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor( _ => "The field is required."); }); builder.Services.AddSingleton <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
IClientModelValidator ügyféloldali ellenőrzéshez
A HTML attribútumok megjelenítésének ezen módszerét a data- attribútum használja a ClassicMovieWithClientValidator. Ügyfélérvényesítés hozzáadása ezzel a módszerrel:
Az egyéni érvényesítési attribútumban implementálja az interfészt IClientModelValidator , és hozzon létre egy metódust AddValidation . A metódusban
AddValidationadjon hozzádata-attribútumokat az ellenőrzéshez, ahogyan az a következő példában látható: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; } }
Ügyféloldali érvényesítés letiltása
Az alábbi kód letiltja az ügyfélérvényesítést a Pagesben Razor :
builder.Services.AddRazorPages()
.AddViewOptions(options =>
{
options.HtmlHelperOptions.ClientValidationEnabled = false;
});
További lehetőségek az ügyféloldali érvényesítés letiltására:
- Az összes
_ValidationScriptsPartialfájlban kommenteljük ki a.cshtmlhivatkozást. - Távolítsa el a Pages\Shared_ValidationScriptsPartial.cshtml fájl tartalmát.
Az előző megközelítés nem akadályozza meg a ASP.NET Core IdentityRazor osztálykódtár ügyféloldali ellenőrzését. További információ: Állványzat Identity ASP.NET Core-projektekben.
További erőforrások
Ez a cikk bemutatja, hogyan érvényesítheti a felhasználói bemenetet egy ASP.NET Core MVC- vagy Razor Pages-alkalmazásban.
Mintakód megtekintése vagy letöltése (hogyan töltsük le).
Modell állapota
A modellállapot két alrendszer hibáit jelöli: a modellkötést és a modellérvényesítést. A modellkötésből származó hibák általában adatkonvertálási hibák. Egy "x" például egy egész számmezőbe van beírva. A modell érvényesítése a modellkötés után történik, és olyan hibákat jelez, amelyekben az adatok nem felelnek meg az üzleti szabályoknak. Például egy 0 értéket ad meg egy olyan mezőben, amely 1 és 5 közötti értékelést vár.
A modellkötés és a modell érvényesítése is egy vezérlőművelet vagy egy Razor Pages-kezelő metódus végrehajtása előtt történik. A webalkalmazások esetében az alkalmazás feladata, hogy megvizsgálja ModelState.IsValid, és megfelelően reagáljon. A webalkalmazások általában egy hibaüzenettel ismételik meg a lapot:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Movies.Add(Movie);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
A webes API-vezérlőknek nem kell ellenőrizniük ModelState.IsValid , hogy rendelkeznek-e az [ApiController] attribútummal. Ebben az esetben a rendszer a hibaadatokat tartalmazó automatikus HTTP 400-választ adja vissza, ha a modell állapota érvénytelen. További információ: Automatikus HTTP 400-válaszok.
Újrafuttatás ellenőrzése
Az érvényesítés automatikus, de előfordulhat, hogy manuálisan szeretné megismételni. Előfordulhat például, hogy egy tulajdonság értékét számítja ki, és újra szeretné futtatni az ellenőrzést, miután a tulajdonságot a kiszámított értékre állítja. Az érvényesítés újrafuttatásához először hívja meg a modellre vonatkozó ellenőrzés törléséhez a ModelStateDictionary.ClearValidationState, majd ezt kövesse a TryValidateModel meghívásával.
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");
}
Érvényesítési attribútumok
Az érvényesítési attribútumokkal érvényesítési szabályokat adhat meg a modelltulajdonságokhoz. A mintaalkalmazás alábbi példája egy olyan modellosztályt mutat be, amely érvényesítési attribútumokkal van eljegyzve. Az [ClassicMovie] attribútum egy egyéni érvényesítési attribútum, a többi pedig beépített. Az [ClassicMovieWithClientValidator] nem jelenik meg, amely a testreszabott attribútum megvalósításának egy alternatív módját mutatja be.
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; }
}
Beépített attribútumok
Íme néhány beépített érvényesítési attribútum:
- [ValidateNever]: Azt jelzi, hogy egy tulajdonságot vagy paramétert ki kell zárni az ellenőrzésből.
- [CreditCard]: Ellenőrzi, hogy a tulajdonság rendelkezik-e hitelkártyaformátummal. További jQuery-érvényesítési módszereket igényel.
- [Összehasonlítás]: Ellenőrzi, hogy egy modell két tulajdonsága egyezik-e.
- [EmailAddress]: Ellenőrzi, hogy a tulajdonság e-mail formátumú-e.
- [Telefon]: Ellenőrzi, hogy a tulajdonság telefonszámformátummal rendelkezik-e.
- [Tartomány]: Ellenőrzi, hogy a tulajdonság értéke egy megadott tartományba esik-e.
- [RegularExpression]: Ellenőrzi, hogy a tulajdonság értéke megfelel-e egy megadott reguláris kifejezésnek.
-
[Kötelező]: Ellenőrzi, hogy a mező nem null értékű-e. Az attribútum működésének részleteiért tekintse meg
[Required]az attribútumot . - [StringLength]: Ellenőrzi, hogy egy sztringtulajdonság értéke nem lépi-e túl a megadott hosszkorlátot.
- [URL]: Ellenőrzi, hogy a tulajdonság URL-formátummal rendelkezik-e.
-
[Távoli]: Az ügyfél bemenetének ellenőrzése egy műveletmetódus meghívásával a kiszolgálón. Az attribútum működésének részleteiért tekintse meg
[Remote]az attribútumot .
Az érvényesítési attribútumok teljes listája megtalálható a System.ComponentModel.DataAnnotations névtérben.
Hibaüzenetek
Az érvényesítési attribútumokkal megadhatja az érvénytelen bemenethez megjelenítendő hibaüzenetet. Például:
[StringLength(8, ErrorMessage = "Name length can't be more than 8.")]
Belsőleg az attribútumok meghívják a String.Format-t, használva a mezőnév helyőrzőjét, és néha további helyőrzőket is. Például:
[StringLength(8, ErrorMessage = "{0} length must be between {2} and {1}.", MinimumLength = 6)]
Egy tulajdonságra Name alkalmazva az előző kód által létrehozott hibaüzenet a következő: "A névhossznak 6 és 8 között kell lennie".
Annak kiderítéséhez, hogy String.Format egy adott attribútum hibaüzenete mely paramétereknek lesz átadva, tekintse meg a DataAnnotations forráskódját.
Nem null értékű hivatkozástípusok és [Kötelező] attribútum
Az érvényesítési rendszer úgy kezeli a nem null értékű paramétereket vagy kötött tulajdonságokat, mintha attribútummal [Required(AllowEmptyStrings = true)] rendelkeznének.
A Nullable kontextusok engedélyezésével az MVC implicit módon megkezdi a nem-null értékű tulajdonságok vagy paraméterek érvényesítését, mintha rendelkeznének az [Required(AllowEmptyStrings = true)] attribútummal. Vegye figyelembe a következő kódot:
public class Person
{
public string Name { get; set; }
}
Ha az alkalmazás <Nullable>enable</Nullable> segítségével készült, akkor a Name számára hiányzó érték a JSON-fájlban vagy az űrlap-bejegyzésben érvényesítési hibát eredményez. Nullázható hivatkozástípust használva engedélyezheti a Name tulajdonság számára, hogy null vagy hiányzó értékek legyenek megadva.
public class Person
{
public string? Name { get; set; }
}
Ez a viselkedés letiltható a következő SuppressImplicitRequiredAttributeForNonNullableReferenceTypesbeállítássalStartup.ConfigureServices:
services.AddControllers(options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);
[Kötelező] érvényesítés a kiszolgálón
A kiszolgálón a szükséges érték hiányzik, ha a tulajdonság null értékű. A nem null értékű mezők mindig érvényesek, és az [Required] attribútum hibaüzenete soha nem jelenik meg.
A nem null értékű tulajdonság modellkötése azonban meghiúsulhat, ami hibaüzenetet eredményez, például The value '' is invalid: . Ha egyéni hibaüzenetet szeretne megadni a nem null értékű típusok kiszolgálóoldali érvényesítéséhez, a következő lehetőségek közül választhat:
Tegye a mezőt nullelláthatóvá (például
decimal?helyettdecimal). Nullázható<A T> értéktípusokat a rendszer standard null értékű típusokként kezeli.Adja meg a modellkötés által használandó alapértelmezett hibaüzenetet az alábbi példában látható módon:
services.AddRazorPages() .AddMvcOptions(options => { options.MaxModelValidationErrors = 50; options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor( _ => "The field is required."); }); services.AddSingleton<IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();További információ a modellkötési hibákról, amelyekhez alapértelmezett üzeneteket állíthat be, lásd: DefaultModelBindingMessageProvider.
[Kötelező] ellenőrzés az ügyfélen
A nem null értékű típusok és sztringek eltérően vannak kezelve az ügyfélen a kiszolgálóhoz képest. Az ügyfél oldalán
- Egy érték csak akkor tekinthető jelennek, ha van bemenet megadva. Ezért az ügyféloldali ellenőrzés a nem null értékű típusokat ugyanúgy kezeli, mint a null értékű típusokat.
- A sztringmezőben lévő szóközt a jQuery Validation kötelező metódusa érvényes bemenetnek tekinti. A kiszolgálóoldali ellenőrzés érvénytelennek tekint egy kötelező sztringmezőt, ha csak a szóköz van beírva.
Ahogy korábban említettük, a nem null értékű típusok úgy lesznek kezelve, mintha attribútummal [Required(AllowEmptyStrings = true)] rendelkeznének. Ez azt jelenti, hogy akkor is megkapja az ügyféloldali ellenőrzést, ha nem alkalmazza az [Required(AllowEmptyStrings = true)] attribútumot. Ha azonban nem használja az attribútumot, egy alapértelmezett hibaüzenet jelenik meg. Egyéni hibaüzenet megadásához használja az attribútumot.
[Távoli] attribútum
A [Távoli] attribútum ügyféloldali ellenőrzést valósít meg, amelyhez egy metódus meghívása szükséges a kiszolgálón annak megállapításához, hogy a mezőbemenet érvényes-e. Előfordulhat például, hogy az alkalmazásnak ellenőriznie kell, hogy egy felhasználónév már használatban van-e.
Távoli érvényesítés megvalósítása:
Hozzon létre egy műveletmetódust a JavaScript hívásához. A jQuery Validation remote metódus JSON-választ vár:
-
trueazt jelenti, hogy a bemeneti adatok érvényesek. -
false,undefinedvagynullazt jelenti, hogy a bemenet érvénytelen. Az alapértelmezett hibaüzenet megjelenítése. - Bármely más sztring azt jelenti, hogy a bemenet érvénytelen. A karakterlánc egyéni hibaüzenetként történő megjelenítése.
Íme egy példa egy egyéni hibaüzenetet visszaadó műveletmetódusra:
[AcceptVerbs("GET", "POST")] public IActionResult VerifyEmail(string email) { if (!_userService.VerifyEmail(email)) { return Json($"Email {email} is already in use."); } return Json(true); }-
A modellosztályban jegyzetelje a tulajdonságot egy
[Remote]olyan attribútummal, amely az érvényesítési művelet metódusára mutat, ahogyan az alábbi példában látható:[Remote(action: "VerifyEmail", controller: "Users")] public string Email { get; set; }
További mezők
Az AdditionalFields attribútum tulajdonsága lehetővé teszi a [Remote] mezők kombinációjának ellenőrzését a kiszolgálón lévő adatokkal szemben. Ha például a User modell rendelkezik FirstName és LastName rendelkezik tulajdonságokkal, érdemes lehet ellenőrizni, hogy a meglévő felhasználók nem rendelkeznek-e már ilyen névpárokkal. Az alábbi példa a AdditionalFieldshasználatát mutatja be:
[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; }
AdditionalFields a "FirstName" és a "LastName" sztringek explicit módon beállíthatók, de a nameof operátor használata egyszerűsíti a későbbi refaktorálást. Az érvényesítés műveleti metódusának mind a firstName-t, mind a lastName-t el kell fogadnia.
[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);
}
Amikor a felhasználó vezeték- vagy utónevet ad meg, a JavaScript távoli hívást indít annak megtekintéséhez, hogy a névpár létrejött-e.
Két vagy több további mező érvényesítéséhez adja meg őket vesszővel tagolt listaként. Ha például egy tulajdonságot MiddleName szeretne hozzáadni a modellhez, állítsa be az [Remote] attribútumot az alábbi példában látható módon:
[Remote(action: "VerifyName", controller: "Users", AdditionalFields = nameof(FirstName) + "," + nameof(LastName))]
public string MiddleName { get; set; }
AdditionalFields, mint minden attribútumargumentum, állandó kifejezésnek kell lennie. Ezért ne használjon interpolált sztringet vagy hívjon meg Join inicializáláshoz AdditionalFields.
A beépített attribútumok alternatívái
Ha nem a beépített attribútumok által biztosított ellenőrzésre van szüksége, a következőkre van szüksége:
Egyéni attribútumok
Olyan forgatókönyvek esetén, amelyeket a beépített érvényesítési attribútumok nem kezelnek, egyéni érvényesítési attribútumokat hozhat létre. Hozzon létre egy olyan osztályt, amely örököl a ValidationAttribute osztályból, és írja felül a IsValid metódust.
A IsValid metódus elfogad egy érték nevű objektumot, amely az érvényesítendő bemenet. A túlterhelés egy objektumot is elfogad ValidationContext , amely további információkat nyújt, például a modellkötés által létrehozott modellpéldányt.
Az alábbi példa ellenőrzi, hogy a klasszikus műfajban lévő filmek megjelenési dátuma nem későbbi-e, mint egy adott év. Az [ClassicMovie] attribútum:
- Csak a kiszolgálón fut.
- Klasszikus filmek esetén ellenőrzi a kiadás dátumának érvényességét:
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;
}
}
Az movie előző példában szereplő változó egy Movie objektumot jelöl, amely az űrlapbeküldésből származó adatokat tartalmazza. Ha az ellenőrzés sikertelen, a ValidationResult rendszer hibaüzenetet ad vissza.
IValidatableObject
Az előző példa csak típusokkal Movie működik. Az osztályszintű ellenőrzés másik lehetősége a modellosztályban való implementálás IValidatableObject , ahogyan az alábbi példában látható:
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) });
}
}
}
Felső szintű csomópont érvényesítés
A legfelső szintű csomópontok a következők:
- Műveleti paraméterek
- Vezérlő tulajdonságai
- Lapkezelő paraméterei
- Lapmodell tulajdonságai
A modellhez kötött legfelső szintű csomópontok érvényesítésre kerülnek a modelltulajdonságok érvényesítésén felül. A mintaalkalmazás alábbi példájában a VerifyPhone metódus a RegularExpressionAttribute felhasználásával érvényesíti a phone műveletparamétert.
[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);
}
A legfelső szintű csomópontok érvényesítési attribútumokkal használhatók BindRequiredAttribute . A mintaalkalmazás alábbi példájában a CheckAge metódus azt határozza meg, hogy a age paramétert a lekérdezési sztringhez kell kötni az űrlap elküldésekor:
[HttpPost]
public IActionResult CheckAge([BindRequired, FromQuery] int age)
{
A Kor ellenőrzése lapon (CheckAge.cshtml) két űrlap található. Az első űrlap egy lekérdezési sztringparaméterként az Age értéket küldi el: 99.
Ha a lekérdezési sztringből megfelelően formázott age paramétert küld el, az űrlap érvényesíti.
Az Életkor ellenőrzése lapon található második űrlap elküldi az Age értéket a kérelem törzsében, és az ellenőrzés sikertelen. A kötés meghiúsul, mert a age paraméternek egy lekérdezési sztringből kell származnia.
Hibák maximális száma
Az érvényesítés a hibák maximális számának elérésekor (alapértelmezés szerint 200) leáll. Ezt a számot a következő kóddal konfigurálhatja:Startup.ConfigureServices
services.AddRazorPages()
.AddMvcOptions(options =>
{
options.MaxModelValidationErrors = 50;
options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
_ => "The field is required.");
});
services.AddSingleton<IValidationAttributeAdapterProvider,
CustomValidationAttributeAdapterProvider>();
Maximális rekurzió
ValidationVisitor bejárja az érvényesítendő modell objektumgráfját. Azoknál a modelleknél, amelyek mélyek vagy végtelenül rekurzívek, az érvényesítés veremtúlcsorduláshoz vezethet.
MvcOptions.MaxValidationDepth lehetővé teszi az ellenőrzés korai leállítását, ha a látogató rekurziója meghaladja a beállított mélységet. Az alapértelmezett érték MvcOptions.MaxValidationDepth 32.
Automatikus rövidzárlat
Az ellenőrzést automatikusan rövidre zárjuk (kihagyjuk), ha a modellgráf nem igényel ellenőrzést. Azok az objektumok, amelyek esetében a futtatókörnyezet kihagyja az ellenőrzést, primitív gyűjteményeket (például byte[], string[], ) Dictionary<string, string>és olyan összetett objektumgráfokat tartalmaznak, amelyek nem rendelkeznek érvényesítőkkel.
Ügyféloldali ellenőrzés
Az ügyféloldali ellenőrzés megakadályozza a beküldést, amíg az űrlap érvényes nem lesz. A Küldés gomb javaScriptet futtat, amely elküldi az űrlapot, vagy hibaüzeneteket jelenít meg.
Az ügyféloldali érvényesítés elkerüli a kiszolgáló szükségtelen oda-vissza utazását, ha bemeneti hibák jelentkeznek egy űrlapon. Az ügyféloldali érvényesítést _Layout.cshtml_ValidationScriptsPartial.cshtml a következő szkripthivatkozások támogatják:
<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>
A jQuery Unobtrusive Validation szkript egy egyéni Microsoft előtér-kódtár, amely a népszerű jQuery Validation beépülő modulra épül. A jQuery Unobtrusive Validation nélkül ugyanazt az érvényesítési logikát két helyen kell kódolva lennie: egyszer a modelltulajdonságok kiszolgálóoldali érvényesítési attribútumaiban, majd ismét az ügyféloldali szkriptekben. Ehelyett a címkesegítők és a HTML-segítők az érvényesítési attribútumokat használják, és a modelltulajdonságok metaadatainak beírásával renderelik az érvényesítésre szoruló űrlapelemek HTML 5 data- attribútumait. A jQuery Unobtrusive Validation elemzi az data- attribútumokat, és átadja a logikát a jQuery Validationnek, és hatékonyan "másolja" a kiszolgálóoldali érvényesítési logikát az ügyfélre. Az ügyféloldalon érvényesítési hibákat jeleníthet meg az itt látható címkesegítők használatával:
<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>
Az előző címkesegítők a következő HTML-t jelenítik meg:
<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>
Figyelje meg, hogy a data- HTML-kimenet attribútumai megfelelnek a tulajdonság érvényesítési attribútumainak Movie.ReleaseDate . Az data-val-required attribútum egy hibaüzenetet tartalmaz, amely akkor jelenik meg, ha a felhasználó nem tölti ki a kiadási dátum mezőt. A jQuery Unobtrusive Validation ezt az értéket átadja a jQuery Validation required() metódusnak , amely ezután megjeleníti az üzenetet a kísérő <span> elemben.
Az adattípus-ellenőrzés egy tulajdonság .NET-típusán alapul, kivéve, ha egy [DataType] attribútum felülírja. A böngészők saját alapértelmezett hibaüzenetekkel rendelkeznek, de a jQuery Validation Unobtrusive Validation csomag felülírhatja ezeket az üzeneteket.
[DataType] attribútumok és alosztályok, például a [EmailAddress] lehetővé teszik a hibaüzenet megadását.
Nem feltűnő ellenőrzés
A nem zavaró ellenőrzéssel kapcsolatos információkért tekintse meg ezt a GitHub-problémát.
Érvényesítés hozzáadása dinamikus űrlapokhoz
JQuery Unobtrusive Validation átadja az érvényesítési logikát és paramétereket a jQuery Validationnek az oldal első betöltésekor. Ezért az ellenőrzés nem működik automatikusan a dinamikusan létrehozott űrlapokon. Az érvényesítés engedélyezéséhez kérje meg a jQuery Nem feltűnő érvényesítés parancsot, hogy közvetlenül a létrehozás után elemezni tudja a dinamikus űrlapot. Az alábbi kód például egy AJAX-en keresztül hozzáadott űrlapon állítja be az ügyféloldali ellenőrzést.
$.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);
}
})
A $.validator.unobtrusive.parse() metódus egy jQuery-választót fogad el egyetlen argumentumához. Ez a módszer utasítja a jQuery Unobtrusive Validationt arra, hogy elemezze a data- attribútumokat a választóban lévő űrlapokon. Az attribútumok értékei ezután átadódnak a jQuery Validation beépülő modulnak.
Ellenőrzés hozzáadása dinamikus vezérlőkhöz
A $.validator.unobtrusive.parse() metódus egy teljes űrlapon működik, nem pedig az egyes dinamikusan létrehozott vezérlőkön, mint például <input> és <select/>. Az űrlap újraelemzéséhez távolítsa el az űrlap korábbi elemzésekor hozzáadott érvényesítési adatokat az alábbi példában látható módon:
$.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);
}
})
Egyéni ügyféloldali ellenőrzés
Az egyéni ügyféloldali érvényesítés egy egyéni jQuery validation adapterrel működő HTML-attribútumok létrehozásával data- történik. A következő mintaadapter-kód a korábban ebben a cikkben bevezetett [ClassicMovie] és [ClassicMovieWithClientValidator] attribútumokhoz készült:
$.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;
});
Az adapterek írásával kapcsolatos információkért tekintse meg a jQuery Validation dokumentációját.
Az adapter használatát egy adott mezőhöz a következő attribútumok data- váltják ki:
- A mező megjelölése ellenőrzés tárgyát képezőként (
data-val="true"). - Azonosítsa az érvényesítési szabály nevét és a hibaüzenet szövegét (például
data-val-rulename="Error message."). - Adjon meg minden további paramétert, amelyekre az érvényesítőnek szüksége van (például
data-val-rulename-param1="value").
Az alábbi példa a data-mintaalkalmazás attribútumainak attribútumaitClassicMovie mutatja be:
<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="">
Ahogy korábban említettük, a címkesegítők és a HTML-segítők az érvényesítési attribútumokból származó információkat használják az attribútumok rendereléséhez data- . A kódírásnak két lehetősége van, amelyek egyéni data- HTML-attribútumok létrehozását eredményezik:
- Hozzon létre egy olyan osztályt, amely származik AttributeAdapterBase<TAttribute> , és egy olyan osztályt, amely megvalósítja IValidationAttributeAdapterProvider, és regisztrálja az attribútumot és annak adapterét a DI-ben. Ez a módszer az egyetlen felelősség elvét követi abban az esetben, ha a kiszolgálóhoz és az ügyfélhez kapcsolódó érvényesítési kód külön osztályokban van. Az adapternek az az előnye is, hogy mivel regisztrálva van a DI-ben, a DI más szolgáltatásai is elérhetők, ha szükséges.
- Implementálja IClientModelValidator az ValidationAttribute osztályban. Ez a módszer akkor lehet megfelelő, ha az attribútum nem végez kiszolgálóoldali ellenőrzést, és nincs szüksége a diától származó szolgáltatásokra.
Attribútumadapter ügyféloldali ellenőrzéshez
A HTML attribútumok megjelenítésének ezen módszerét a data- attribútum használja a ClassicMovie. Ügyfélérvényesítés hozzáadása ezzel a módszerrel:
Hozzon létre egy attribútumadapter-osztályt az egyéni érvényesítési attribútumhoz. Az osztály származtatása a következőből: AttributeAdapterBase<TAttribute>. Hozzon létre egy metódust
AddValidation, amely attribútumokatdata-ad hozzá a renderelt kimenethez az alábbi példában látható módon: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(); }Hozzon létre egy adapter szolgáltató osztályt, amely implementálja a IValidationAttributeAdapterProvider-t. GetAttributeAdapter A metódusban adja át az egyéni attribútumot az adapter konstruktorának, ahogyan az ebben a példában látható:
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); } }Regisztrálja a DI-hez tartozó adapterszolgáltatót a következő helyen
Startup.ConfigureServices:services.AddRazorPages() .AddMvcOptions(options => { options.MaxModelValidationErrors = 50; options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor( _ => "The field is required."); }); services.AddSingleton<IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
IClientModelValidator ügyféloldali ellenőrzéshez
A HTML attribútumok megjelenítésének ezen módszerét a data- attribútum használja a ClassicMovieWithClientValidator. Ügyfélérvényesítés hozzáadása ezzel a módszerrel:
Az egyéni érvényesítési attribútumban implementálja az interfészt IClientModelValidator , és hozzon létre egy metódust AddValidation . A metódusban
AddValidationadjon hozzádata-attribútumokat az ellenőrzéshez, ahogyan az a következő példában látható: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; } }
Ügyféloldali érvényesítés letiltása
Az alábbi kód letiltja az ügyfélérvényesítést a Pagesben Razor :
services.AddRazorPages()
.AddViewOptions(options =>
{
options.HtmlHelperOptions.ClientValidationEnabled = false;
});
További lehetőségek az ügyféloldali érvényesítés letiltására:
- Az összes
_ValidationScriptsPartialfájlban kommenteljük ki a.cshtmlhivatkozást. - Távolítsa el a Pages\Shared_ValidationScriptsPartial.cshtml fájl tartalmát.
Az előző megközelítés nem akadályozza meg a ASP.NET Core IdentityRazor osztálykódtár ügyféloldali ellenőrzését. További információ: Állványzat Identity ASP.NET Core-projektekben.