asp.net-mvc
Annotazioni di dati
Ricerca…
introduzione
Possiamo aggiungere validazioni alla nostra applicazione aggiungendo annotazioni di dati alle nostre classi di modelli. Le annotazioni dei dati ci consentono di descrivere le regole che vogliamo applicare alle nostre proprietà del modello e ASP.NET MVC si prenderà cura di applicarle e di visualizzare messaggi appropriati agli utenti.
Attributi di convalida di base utilizzati in ViewModel
Modello
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; }
}
vista
// 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" />
}
controllore
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);
}
}
Convalida remota
La convalida remota utilizzata per verificare se il contenuto immesso nel controllo di input è valida o meno inviando una richiesta Ajax al lato server per controllarlo.
Lavoro
RemoteAttribute
funziona effettuando una chiamata AJAX dal client a un'azione del controller con il valore del campo che viene convalidato. L'azione del controller restituisce quindi una risposta JsonResult
indica che la convalida ha esito positivo o negativo. Restituendo true
dalla tua azione indica che la validazione è stata superata. Qualsiasi altro valore indica un errore. Se si restituisce false
, viene utilizzato il messaggio di errore specificato nell'attributo. Se si restituisce qualcos'altro come una stringa o anche un numero intero, verrà visualizzato come messaggio di errore. A meno che non sia necessario che il messaggio di errore sia dinamico, è opportuno restituire true o false e lasciare che il validatore utilizzi il messaggio di errore specificato sull'attributo.
ViewModel
public class ViewModel
{
[Remote("IsEmailAvailable", "Group", HttpMethod = "POST", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email{ get; set; }
}
controllore
[HttpPost]
public JsonResult IsEmailAvailable(string Email)
{
// Logic to check whether email is already registered or Not.
var emailExists = IsEmailRegistered();
return Json(!emailExists);
}
È possibile passare proprietà aggiuntive del modello al metodo controller utilizzando la proprietà AdditionalFields
di RemoteAttribute
. Uno scenario tipico sarebbe quello di passare la proprietà ID del modello in un modulo 'Modifica', in modo che la logica del controller possa ignorare i valori per il record esistente.
Modello
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; }
controllore
[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);
}
}
Demo di lavoro: campi aggiuntivi
Nota aggiuntiva
Il messaggio di errore predefinito è comprensibilmente vago, quindi ricorda sempre di sovrascrivere il messaggio di errore predefinito quando si utilizza RemoteAttribute
.
RequiredAttribute
L'attributo Required
specifica che è richiesta una proprietà. È possibile specificare un messaggio di errore sull'utilizzo della proprietà ErrorMessage
sull'attributo.
Per prima cosa aggiungi lo spazio dei nomi:
using System.ComponentModel.DataAnnotations;
E applica l'attributo su una proprietà.
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; }
}
È anche possibile utilizzare le risorse nel messaggio di errore per le applicazioni globalizzate. In questo caso, ErrorMessageResourceName
deve essere specificato con la chiave di risorsa della classe di risorsa (file resx
) che deve essere impostata su 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
L'attributo StringLength
specifica la lunghezza minima e massima dei caratteri consentiti in un campo dati. Questo attributo può essere applicato su proprietà, campi pubblici e parametri. Il messaggio di errore deve essere specificato sulla proprietà ErrorMessage
sull'attributo. Le proprietà MinimumLength
e MaximumLength
specificano rispettivamente il minimo e il massimo.
Per prima cosa aggiungi lo spazio dei nomi:
using System.ComponentModel.DataAnnotations;
E applica l'attributo su una proprietà.
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; }
}
È anche possibile utilizzare le risorse nel messaggio di errore per le applicazioni globalizzate. In questo caso, ErrorMessageResourceName
deve essere specificato con la chiave di risorsa della classe di risorsa (file resx
) che deve essere impostata su 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; }
}
Range Attribute
L'attributo Range
può decorare qualsiasi proprietà o campo pubblico e specifica un intervallo che deve essere compreso tra un campo numerico e un valore valido.
[Range(minimumValue, maximumValue)]
public int Property { get; set; }
Inoltre, accetta una proprietà ErrorMessage
facoltativa che può essere utilizzata per impostare il messaggio ricevuto dall'utente quando vengono immessi dati non validi:
[Range(minimumValue, maximumValue, ErrorMessage = "{your-error-message}")]
public int Property { get; set; }
Esempio
[Range(1,100, ErrorMessage = "Ranking must be between 1 and 100.")]
public int Ranking { get; set; }
Attributo RegularExpression
L'attributo [RegularExpression]
può decorare qualsiasi proprietà o campo pubblico e specifica un'espressione regolare che deve essere associata affinché la proprietà sia considerata valida.
[RegularExpression(validationExpression)]
public string Property { get; set; }
Inoltre, accetta una proprietà ErrorMessage
facoltativa che può essere utilizzata per impostare il messaggio ricevuto dall'utente quando vengono immessi dati non validi:
[RegularExpression(validationExpression, ErrorMessage = "{your-error-message}")]
public string Property { get; set; }
Esempio (s)
[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; }
Confronta l'attributo
L'attributo Compare
confronta due proprietà di un modello.
Il messaggio di errore può essere specificato utilizzando la proprietà ErrorMessage
o utilizzando i file di risorse.
Per utilizzare l'attributo Compare
using
per il seguente spazio dei nomi:
using System.ComponentModel.DataAnnotations;
Quindi puoi usare l'attributo nel tuo modello:
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; }
}
Quando questo modello è valido, se Email
e ConfirmEmail
hanno valori diversi, la convalida fallirà.
Messaggi di errore localizzati
Proprio come con tutti gli attributi di convalida, è possibile utilizzare i messaggi di errore dai file di risorse. In questo esempio il messaggio di errore verrà caricato dal file di Resources
. Resources
, il nome della risorsa è CompareValidationMessage
:
public class RegisterModel
{
public string Email { get; set; }
["Email", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "CompareValidationMessage")]
public string ConfirmEmail { get; set; }
}
Evita le stringhe nei nomi delle proprietà
Per evitare l'uso della stringa per il valore della proprietà, in C # 6+ è possibile utilizzare la parola chiave 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; }
}
Segnaposti nei messaggi di errore
Puoi usare segnaposto nei tuoi messaggi di errore. Il segnaposto {0}
viene sostituito con il nome visualizzato della proprietà corrente e {1}
viene sostituito con il nome visualizzato della proprietà correlata:
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; }
}
Se la validazione del modello fallisce, il messaggio di errore sarà
I campi "Email" e "Conferma email" non corrispondono.
Attributo di convalida personalizzato
Quando si tratta di convalidare alcune regole che non sono la convalida dei dati generici, ad esempio assicurandosi che sia richiesto un campo o qualche intervallo di valori, ma sono specifici per la propria logica aziendale, è possibile creare il proprio Validatore personalizzato . Per creare un attributo di convalida personalizzato, devi solo inherit
classe ValidationAttribute
e override
suo metodo IsValid
. Il metodo IsValid
accetta due parametri, il primo è un object
denominato come value
e il secondo è un ValidationContext object
denominato come validationContext
. Value
riferisce al valore effettivo dal campo che il validatore personalizzato sta per convalidare.
Supponiamo di voler convalidare l' Email
- Email
tramite il Custom Validator
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; }
}
Ecco la sua Demo DotNetFiddle
Modello EDMx - Annotazione dei dati
Edmx model internel
public partial class ItemRequest
{
public int RequestId { get; set; }
//...
}
Aggiungendo annotazioni dati a questo - se modifichiamo direttamente questo modello, quando viene effettuato un aggiornamento al modello, le modifiche vengono perse. così
Per aggiungere un attributo in questo caso 'Richiesto'
Crea una nuova classe - qualsiasi nome Quindi
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;}
//...
}
}
o
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 */
}
}
Annotazioni dei dati per la prima implementazione del database (codice del modello generato automaticamente)
[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; }
}
Se hai utilizzato il database prima e il codice del tuo modello è stato generato automaticamente, questo messaggio verrà visualizzato sopra il tuo codice modello:
Questo codice è stato generato da un modello. Le modifiche manuali a questo file possono causare un comportamento imprevisto nell'applicazione. Le modifiche manuali a questo file verranno sovrascritte se il codice viene rigenerato
Se si desidera utilizzare le annotazioni dei dati e non si desidera che vengano sovrascritte se si aggiorna l'edmx è sufficiente aggiungere un'altra classe parziale alla cartella del modello simile all'esempio precedente.