asp.net-mvc
Adnotacje danych
Szukaj…
Wprowadzenie
Możemy dodać weryfikacje do naszej aplikacji, dodając adnotacje danych do naszych klas modeli. Adnotacje danych pozwalają nam opisać reguły, które chcemy zastosować do właściwości naszego modelu, a ASP.NET MVC zajmie się ich egzekwowaniem i wyświetlaniem odpowiednich komunikatów dla użytkowników.
Podstawowe atrybuty sprawdzania poprawności używane w ViewModel
Model
using System.ComponentModel.DataAnnotations;
public class ViewModel
{
[Required(ErrorMessage="Name is required")]
public string Name { get; set; }
[StringLength(14, MinimumLength = 14, ErrorMessage = "Invalid Phone Number")]
[Required(ErrorMessage="Phone Number is required")]
public string PhoneNo { get; set; }
[Range(typeof(decimal), "0", "150")]
public decimal? Age { get; set; }
[RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Invalid Zip Code.")]
public string ZipCode {get;set;}
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
[Editable(false)]
public string Address{ get; set; }
}
Widok
// Include Jquery and Unobstructive Js here for client side validation
@using (Html.BeginForm("Index","Home") {
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
@Html.TextBoxFor(model => model.PhoneNo)
@Html.ValidationMessageFor(model => model.PhoneNo)
@Html.TextBoxFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
@Html.TextBoxFor(model => model.ZipCode)
@Html.ValidationMessageFor(model => model.ZipCode)
@Html.TextBoxFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
@Html.TextBoxFor(model => model.Address)
@Html.ValidationMessageFor(model => model.Address)
<input type="submit" value="submit" />
}
Kontroler
public ActionResult Index(ViewModel _Model)
{
// Checking whether the Form posted is valid one.
if(ModelState.IsValid)
{
// your model is valid here.
// perform any actions you need to, like database actions,
// and/or redirecting to other controllers and actions.
}
else
{
// redirect to same action
return View(_Model);
}
}
Zdalna walidacja
Zdalna walidacja służy do sprawdzania, czy treść wprowadzana do formantu wejściowego jest poprawna, czy nie, wysyłając żądanie ajax do strony serwera, aby to sprawdzić.
Pracujący
RemoteAttribute
działa poprzez wykonanie wywołania AJAX od klienta do akcji kontrolera z wartością walidowanego pola. Następnie działanie kontrolera zwraca odpowiedź JsonResult
wskazującą powodzenie lub niepowodzenie sprawdzania poprawności. Zwrócenie wartości true
z działania oznacza, że sprawdzanie poprawności zostało zakończone. Każda inna wartość wskazuje na awarię. Jeśli zwrócisz wartość false
, użyty zostanie komunikat o błędzie określony w atrybucie. Jeśli zwrócisz coś innego, na przykład ciąg, a nawet liczbę całkowitą, zostanie wyświetlony jako komunikat o błędzie. O ile komunikat o błędzie nie musi być dynamiczny, warto zwrócić wartość true lub false i pozwolić walidatorowi użyć komunikatu o błędzie określonego w atrybucie.
ViewModel
public class ViewModel
{
[Remote("IsEmailAvailable", "Group", HttpMethod = "POST", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email{ get; set; }
}
Kontroler
[HttpPost]
public JsonResult IsEmailAvailable(string Email)
{
// Logic to check whether email is already registered or Not.
var emailExists = IsEmailRegistered();
return Json(!emailExists);
}
Możesz przekazać dodatkowe właściwości modelu do metody kontrolera za pomocą właściwości AdditionalFields
RemoteAttribute
. Typowym scenariuszem byłoby przekazanie właściwości ID modelu w formie „Edycja”, aby logika kontrolera mogła zignorować wartości dla istniejącego rekordu.
Model
public int? ID { get; set; }
[Display(Name = "Email address")]
[DataType(DataType.EmailAddress)]
[Required(ErrorMessage = "Please enter you email address")]
[Remote("IsEmailAvailable", HttpMethod="Post", AdditionalFields="ID", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email { get; set; }
Kontroler
[HttpPost]
public ActionResult Validate(string email, int? id)
{
if (id.HasValue)
{
return Json(!db.Users.Any(x => x.Email == email && x.ID != id);
}
else
{
return Json(!db.Users.Any(x => x.Email == email);
}
}
Uwaga dodatkowa
Domyślny komunikat o błędzie jest zrozumiały, dlatego zawsze pamiętaj o zastąpieniu domyślnego komunikatu o błędzie podczas korzystania z RemoteAttribute
.
RequiredAttribute
Required
atrybut określa, że właściwość jest wymagana. Komunikat o błędzie można określić przy użyciu właściwości ErrorMessage
w atrybucie.
Najpierw dodaj przestrzeń nazw:
using System.ComponentModel.DataAnnotations;
I zastosuj atrybut do właściwości.
public class Product
{
[Required(ErrorMessage = "The product name is required.")]
public string Name { get; set; }
[Required(ErrorMessage = "The product description is required.")]
public string Description { get; set; }
}
Możliwe jest również użycie zasobów w komunikacie o błędzie dla zglobalizowanych aplikacji. W takim przypadku parametr ErrorMessageResourceName
należy podać za pomocą klucza zasobu klasy zasobów (pliku resx
), który należy ustawić w parametrze ErrorMessageResourceType
:
public class Product
{
[Required(ErrorMessageResourceName = "ProductNameRequired",
ErrorMessageResourceType = typeof(ResourceClass))]
public string Name { get; set; }
[Required(ErrorMessageResourceName = "ProductDescriptionRequired",
ErrorMessageResourceType = typeof(ResourceClass))]
public string Description { get; set; }
}
StringLengthAttribute
Atrybut StringLength
określa minimalną i maksymalną długość znaków dozwolonych w polu danych. Ten atrybut można zastosować do właściwości, pól publicznych i parametrów. Komunikat o błędzie musi zostać określony we właściwości ErrorMessage
w atrybucie. Właściwości MinimumLength
MaximumLength
i Maksymalna MaximumLength
określają odpowiednio minimum i maksimum.
Najpierw dodaj przestrzeń nazw:
using System.ComponentModel.DataAnnotations;
I zastosuj atrybut do właściwości.
public class User
{
// set the maximum
[StringLength(20, ErrorMessage = "The username cannot exceed 20 characters. ")]
public string Username { get; set; }
[StringLength(MinimumLength = 3, MaximumLength = 16, ErrorMessage = "The password must have between 3 and 16 characters.")]
public string Password { get; set; }
}
Możliwe jest również użycie zasobów w komunikacie o błędzie dla zglobalizowanych aplikacji. W takim przypadku parametr ErrorMessageResourceName
należy podać za pomocą klucza zasobu klasy zasobów (pliku resx
), który należy ustawić w parametrze ErrorMessageResourceType
:
public class User
{
[StringLength(20, ErrorMessageResourceName = "StringLength",
ErrorMessageResourceType = typeof(ResoucesKeys))]
public string Username { get; set; }
[StringLength(MinimumLength = 3,
MaximumLength = 16,
ErrorMessageResourceName = "StringLength",
ErrorMessageResourceType = typeof(ResoucesKeys))]
public string Password { get; set; }
}
Atrybut zakresu
Atrybut Range
może ozdobić dowolne właściwości lub pola publiczne i określa zakres, między którym pole numeryczne musi się mieścić, aby zostało uznane za prawidłowe.
[Range(minimumValue, maximumValue)]
public int Property { get; set; }
Ponadto akceptuje opcjonalną właściwość ErrorMessage
której można użyć do ustawienia wiadomości otrzymanej przez użytkownika po wprowadzeniu nieprawidłowych danych:
[Range(minimumValue, maximumValue, ErrorMessage = "{your-error-message}")]
public int Property { get; set; }
Przykład
[Range(1,100, ErrorMessage = "Ranking must be between 1 and 100.")]
public int Ranking { get; set; }
Atrybut RegularExpression
Atrybut [RegularExpression]
może ozdobić dowolne właściwości lub pola publiczne i określa wyrażenie regularne, które należy dopasować, aby właściwość została uznana za prawidłową.
[RegularExpression(validationExpression)]
public string Property { get; set; }
Ponadto akceptuje opcjonalną właściwość ErrorMessage
której można użyć do ustawienia wiadomości otrzymanej przez użytkownika po wprowadzeniu nieprawidłowych danych:
[RegularExpression(validationExpression, ErrorMessage = "{your-error-message}")]
public string Property { get; set; }
Przykład (y)
[RegularExpression(@"^[a-z]{8,16}?$", ErrorMessage = "A User Name must consist of 8-16 lowercase letters")]
public string UserName{ get; set; }
[RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Please enter a valid ZIP Code (e.g. 12345, 12345-1234)")]
public string ZipCode { get; set; }
Porównaj atrybut
Atrybut Compare
porównuje dwie właściwości modelu.
Komunikat o błędzie można określić za pomocą właściwości ErrorMessage
lub przy użyciu plików zasobów.
Aby użyć atrybutu Compare
należy using
dla następującej przestrzeni nazw:
using System.ComponentModel.DataAnnotations;
Następnie możesz użyć atrybutu w swoim modelu:
public class RegisterModel
{
public string Email { get; set; }
[Compare("Email", ErrorMessage = "The Email and Confirm Email fields do not match.")]
public string ConfirmEmail { get; set; }
}
Gdy ten model jest sprawdzany, jeśli Email
i ConfirmEmail
mają różne wartości, sprawdzanie poprawności zakończy się niepowodzeniem.
Zlokalizowane komunikaty o błędach
Podobnie jak w przypadku wszystkich atrybutów sprawdzania poprawności, można używać komunikatów o błędach z plików zasobów. W tym przykładzie komunikat o błędzie zostanie załadowany z pliku Resources
, nazwa zasobu to CompareValidationMessage
:
public class RegisterModel
{
public string Email { get; set; }
["Email", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "CompareValidationMessage")]
public string ConfirmEmail { get; set; }
}
Unikaj ciągów w nazwach właściwości
Aby uniknąć użycia ciągu jako wartości właściwości, w C # 6+ można użyć parametru nameof
:
public class RegisterModel
{
public string Email { get; set; }
[Compare(nameof(Email), ErrorMessage = "The Email and Confirm Email fields do not match.")]
public string ConfirmEmail { get; set; }
}
Symbole zastępcze w komunikatach o błędach
W komunikatach o błędach można używać symboli zastępczych. Symbol zastępczy {0}
zostaje zastąpiony nazwą wyświetlaną bieżącej właściwości, a {1}
zostaje zastąpiony nazwą wyświetlaną powiązanej właściwości:
public class RegisterModel
{
[Display(Name = "Email")]
public string Email { get; set; }
[Display(Name = "Confirm Email")]
[Compare("Email", ErrorMessage = "The '{1}' and '{0}' fields do not match.")]
public string ConfirmEmail { get; set; }
}
Jeśli sprawdzanie poprawności modelu nie powiedzie się, pojawi się komunikat o błędzie
Pola „E-mail” i „Potwierdź e-mail” nie pasują do siebie.
Niestandardowy atrybut walidacji
Jeśli chodzi o sprawdzanie poprawności niektórych reguł, które nie są ogólną weryfikacją danych, np. Upewnienie się, że pole jest wymagane lub pewien zakres wartości, ale są one specyficzne dla logiki biznesowej, możesz stworzyć swój własny Walidator . Aby utworzyć niestandardowy atrybut sprawdzania poprawności, wystarczy inherit
klasę ValidationAttribute
i override
jej metodę IsValid
. Metoda IsValid
przyjmuje dwa parametry, pierwszy to object
nazwie value
a drugi to ValidationContext object
nazwie validationContext
. Value
odnosi się do rzeczywistej wartości z pola, którą weryfikator niestandardowy zamierza sprawdzić.
Załóżmy, że chcesz sprawdzić poprawność wiadomości Email
za pomocą Custom Validator
sprawdzania poprawności
public class MyCustomValidator : ValidationAttribute
{
private static string myEmail= "[email protected]";
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string Email = value.ToString();
if(myEmail.Equals(Email))
return new ValidationResult("Email Already Exist");
return ValidationResult.Success;
}
}
public class SampleViewModel
{
[MyCustomValidator]
[Required]
public string Email { get; set; }
public string Name { get; set; }
}
Oto jego demo DotNetFiddle
Model EDMx - adnotacja danych
Model wewnętrzny Edmx
public partial class ItemRequest
{
public int RequestId { get; set; }
//...
}
Dodanie do tego adnotacji danych - jeśli zmodyfikujemy ten model bezpośrednio, po dokonaniu aktualizacji modelu zmiany zostaną utracone. więc
Aby dodać atrybut w tym przypadku „Wymagane”
Utwórz nową klasę - dowolna nazwa
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models
{
[MetadataType(typeof(ItemRequestMetaData))]
public partial class ItemRequest
{
}
public class ItemRequestMetaData
{
[Required]
public int RequestId {get;set;}
//...
}
}
lub
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace YourApplication.Models
{
public interface IEntityMetadata
{
[Required]
Int32 Id { get; set; }
}
[MetadataType(typeof(IEntityMetadata))]
public partial class Entity : IEntityMetadata
{
/* Id property has already existed in the mapped class */
}
}
Adnotacje danych do pierwszej implementacji bazy danych (kod modelu generowany automatycznie)
[MetadataType(typeof(RoleMetaData))]
public partial class ROLE
{
}
public class RoleMetaData
{
[Display(Name = "Role")]
public string ROLE_DESCRIPTION { get; set; }
[Display(Name = "Username")]
public string ROLE_USERNAME { get; set; }
}
Jeśli użyłeś najpierw bazy danych, a kod modelu został wygenerowany automatycznie, ten komunikat pojawi się nad kodem modelu:
Ten kod został wygenerowany z szablonu. Ręczne zmiany w tym pliku mogą powodować nieoczekiwane zachowanie w aplikacji. Ręczne zmiany tego pliku zostaną zastąpione, jeśli kod zostanie zregenerowany
Jeśli chcesz używać adnotacji danych i nie chcesz, aby były one nadpisywane, jeśli odświeżysz edmx, po prostu dodaj kolejną klasę częściową do folderu modelu, która wygląda jak w powyższym przykładzie.