asp.net-mvc
Anotaciones de datos
Buscar..
Introducción
Podemos agregar validaciones a nuestra aplicación al agregar Anotaciones de datos a nuestras clases modelo. Las anotaciones de datos nos permiten describir las reglas que queremos que se apliquen a las propiedades de nuestro modelo, y ASP.NET MVC se encargará de hacerlas cumplir y mostrar los mensajes apropiados a los usuarios.
Atributos básicos de validación utilizados en ViewModel
Modelo
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; }
}
Ver
// 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" />
}
Controlador
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);
}
}
Validación remota
Validación remota utilizada para verificar si el contenido que se ingresa en el control de entrada es válido o no, enviando una solicitud ajax al lado del servidor para verificarlo.
Trabajando
RemoteAttribute
funciona al realizar una llamada AJAX desde el cliente a una acción del controlador con el valor del campo que se está validando. La acción del controlador luego devuelve una respuesta JsonResult
indica el éxito o el fracaso de la validación. Devolviendo true
de su acción indica que la validación pasó. Cualquier otro valor indica falla. Si devuelve false
, se utiliza el mensaje de error especificado en el atributo. Si devuelve algo más, como una cadena o incluso un entero, se mostrará como el mensaje de error. A menos que necesite que su mensaje de error sea dinámico, tiene sentido devolver verdadero o falso y dejar que el validador use el mensaje de error especificado en el atributo.
ViewModel
public class ViewModel
{
[Remote("IsEmailAvailable", "Group", HttpMethod = "POST", ErrorMessage = "Email already exists. Please enter a different email address.")]
public string Email{ get; set; }
}
Controlador
[HttpPost]
public JsonResult IsEmailAvailable(string Email)
{
// Logic to check whether email is already registered or Not.
var emailExists = IsEmailRegistered();
return Json(!emailExists);
}
Puede pasar propiedades adicionales del modelo al método del controlador utilizando la propiedad AdditionalFields
de RemoteAttribute
. Un escenario típico sería pasar la propiedad de ID del modelo en forma de 'Editar', de modo que la lógica del controlador pueda ignorar los valores del registro existente.
Modelo
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; }
Controlador
[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);
}
}
Demostración de trabajo - Campos adicionales
Nota adicional
El mensaje de error predeterminado es comprensiblemente vago, por lo que siempre recuerde anular el mensaje de error predeterminado cuando use el RemoteAttribute
.
RequiredAttribute
El atributo Required
especifica que una propiedad es requerida. Se puede especificar un mensaje de error al usar la propiedad ErrorMessage
en el atributo.
Primero agregue el espacio de nombres:
using System.ComponentModel.DataAnnotations;
Y aplicar el atributo en una propiedad.
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; }
}
También es posible utilizar recursos en el mensaje de error para aplicaciones globalizadas. En este caso, el ErrorMessageResourceName
debe especificarse con la clave de recurso de la clase de recurso (archivo resx
) que debe ErrorMessageResourceType
en el 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
El atributo StringLength
especifica la longitud mínima y máxima de los caracteres permitidos en un campo de datos. Este atributo se puede aplicar en propiedades, campos públicos y parámetros. El mensaje de error se debe especificar en la propiedad ErrorMessage
en el atributo. Las propiedades MinimumLength
y MaximumLength
especifican el mínimo y el máximo respectivamente.
Primero agregue el espacio de nombres:
using System.ComponentModel.DataAnnotations;
Y aplicar el atributo en una propiedad.
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; }
}
También es posible utilizar recursos en el mensaje de error para aplicaciones globalizadas. En este caso, el ErrorMessageResourceName
debe especificarse con la clave de recurso de la clase de recurso (archivo resx
) que debe ErrorMessageResourceType
en el 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; }
}
Atributo de rango
El atributo Range
puede decorar cualquier propiedad o campo público y especifica un rango en el que un campo numérico debe estar entre para ser considerado válido.
[Range(minimumValue, maximumValue)]
public int Property { get; set; }
Además, acepta una propiedad opcional ErrorMessage
que se puede usar para configurar el mensaje recibido por el usuario cuando se ingresan datos no válidos:
[Range(minimumValue, maximumValue, ErrorMessage = "{your-error-message}")]
public int Property { get; set; }
Ejemplo
[Range(1,100, ErrorMessage = "Ranking must be between 1 and 100.")]
public int Ranking { get; set; }
Atributo de expresión regular
El atributo [RegularExpression]
puede decorar cualquier propiedad o campo público y especifica una expresión regular que debe coincidir para que la propiedad se considere válida.
[RegularExpression(validationExpression)]
public string Property { get; set; }
Además, acepta una propiedad opcional ErrorMessage
que se puede usar para configurar el mensaje recibido por el usuario cuando se ingresan datos no válidos:
[RegularExpression(validationExpression, ErrorMessage = "{your-error-message}")]
public string Property { get; set; }
Ejemplo (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; }
Comparar atributo
El atributo de Compare
compara dos propiedades de un modelo.
El mensaje de error se puede especificar usando la propiedad ErrorMessage
o usando archivos de recursos.
Para usar el atributo Compare
incluya using
para el siguiente espacio de nombres:
using System.ComponentModel.DataAnnotations;
Luego puedes usar el atributo en tu modelo:
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; }
}
Cuando se valida este modelo, si Email
y ConfirmEmail
tienen valores diferentes, la validación fallará.
Mensajes de error localizados
Al igual que con todos los atributos de validación, es posible usar mensajes de error de archivos de recursos. En este ejemplo, el mensaje de error se cargará desde los recursos del archivo de Resources
, el nombre del recurso es CompareValidationMessage
:
public class RegisterModel
{
public string Email { get; set; }
["Email", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "CompareValidationMessage")]
public string ConfirmEmail { get; set; }
}
Evitar cadenas en nombres de propiedades
Para evitar utilizar la cadena para el valor de la propiedad, en C # 6+ puede usar la palabra clave 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; }
}
Marcadores de posición en mensajes de error
Puede utilizar marcadores de posición en sus mensajes de error. El marcador de posición {0}
se reemplaza con el nombre de visualización de la propiedad actual y {1}
se reemplaza con el nombre de visualización de la propiedad relacionada:
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; }
}
Si la validación del modelo falla, el mensaje de error será
Los campos 'Correo electrónico' y 'Confirmar correo electrónico' no coinciden.
Atributo de validación personalizado
Cuando se trata de validar algunas reglas que no son validación de datos genéricos, por ejemplo, asegurarse de que se requiere un campo o algún rango de valores, pero que son específicos para su lógica de negocios, puede crear su propio Validador personalizado . Para crear un atributo de validación personalizado, solo necesita inherit
clase ValidationAttribute
y override
su método IsValid
. El método IsValid
toma dos parámetros, el primero es un object
denominado como value
y el segundo es un ValidationContext object
llamado validationContext
. Value
refiere al valor real del campo que va a validar su validador personalizado.
Supongamos que desea validar el Email
través de un 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; }
}
Aquí está su DotNetFiddle Demo
Modelo EDMx - Anotación de datos
Edmx modelo internel
public partial class ItemRequest
{
public int RequestId { get; set; }
//...
}
Agregando anotación de datos a esto: si modificamos este modelo directamente, cuando se realiza una actualización del modelo, los cambios se pierden. asi que
Para agregar un atributo en este caso 'Requerido'
Crear una nueva clase - cualquier nombre Entonces
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 */
}
}
Anotaciones de datos para la primera implementación de la base de datos (código de modelo generado automáticamente)
[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; }
}
Si utilizó la base de datos primero y su código de modelo se generó automáticamente, este mensaje aparecerá sobre su código de modelo:
Este código fue generado a partir de una plantilla. Los cambios manuales en este archivo pueden causar un comportamiento inesperado en su aplicación. Los cambios manuales en este archivo se sobrescribirán si el código se regenera
Si desea usar anotaciones de datos y no desea que se sobrescriban si actualiza el edmx, simplemente agregue otra clase parcial a su carpeta modelo que se parece al ejemplo anterior.