tag route parameter net data asp all .net asp.net-mvc-2 data-annotations asp.net-mvc-2-validation

.net - parameter - asp-route-id



Recurso predeterminado para anotaciones de datos en ASP.NET MVC (3)

Hice otro enfoque. Todavía necesita que herede los atributos de DataAnnotation , pero puede obtener una solución de traducción más flexible.

Código de mi blog (léelo para más detalles)

Resultado final

public class User { [Required] [LocalizedDisplayNameAttribute("User_Id")] public int Id { get; set; } [Required] [StringLength(40)] [LocalizedDisplayNameAttribute("User_FirstName")] public string FirstName { get; set; } [Required] [StringLength(40)] [LocalizedDisplayNameAttribute("User_LastName")] public string LastName { get; set; } }

1 Heredar todos los atributos de anotación de datos como este

public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute { private string _displayName; public RequiredAttribute() { ErrorMessageResourceName = "Validation_Required"; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { _displayName = validationContext.DisplayName; return base.IsValid(value, validationContext); } public override string FormatErrorMessage(string name) { var msg = LanguageService.Instance.Translate(ErrorMessageResourceName); return string.Format(msg, _displayName); } }

2 Hereda DisplayNameAttribute

public class LocalizedDisplayNameAttribute : DisplayNameAttribute { private PropertyInfo _nameProperty; private Type _resourceType; public LocalizedDisplayNameAttribute(string className, string propertyName) : base(className + (propertyName == null ? "_Class" : ("_" + propertyName))) { } public override string DisplayName { get { return LanguageService.Instance.Translate(base.DisplayName) ?? "**" + base.DisplayName + "**"; } } }

3. Cree el servicio de idioma (puede cambiar a cualquier fuente de idioma en él)

public class LanguageService { private static LanguageService _instance = new LanguageService(); private List<ResourceManager> _resourceManagers = new List<ResourceManager>(); private LanguageService() { } public static LanguageService Instance { get { return _instance; } } public void Add(ResourceManager mgr) { _resourceManagers.Add(mgr); } public string Translate(string key) { foreach (var item in _resourceManagers) { var value = item.GetString(key); if (value != null) return value; } return null; } }

Finalmente, debe registrar las tablas de cadenas que utiliza para traducir los mensajes de validación y sus modelos.

LanguageService.Instance.Add(MyNameSpace.ModelResource.ResourceManager); LanguageService.Instance.Add(MyNameSpace.ValidationResources.ResourceManager);

¿Hay una manera de establecer el recurso predeterminado para las validaciones de anotaciones de datos?

No quiero hacer algo como esto:

[Required(ErrorMessage="Name required.", ErrorMessageResourceType=typeof(CustomDataAnnotationsResources)] public string Name { get; set; }

Me gustaría algo como esto:

Global.asax

DataAnnotations.DefaultResources = typeof(CustomDataAnnotationsResources);

entonces

[Required] public string Name { get; set; }

Alguien dame una luz!

gracias por adelantado

EDITAR

Mi verdadero problema fue con EF Code First CTP4. CTP5 lo arregla. Gracias por todo.


Para lograr esto, creé una nueva clase que hereda de RequiredAttribute, y el mensaje de error está incrustado dentro de esta nueva clase:

public class RequiredWithMessageAttribute : RequiredAttribute { public RequiredWithMessageAttribute() { ErrorMessageResourceType = typeof(ValidationResource); ErrorMessageResourceName = "RequiredErrorMessage"; } }

El mensaje de error se toma del archivo ValidationResource.resx, donde enumero el mensaje de error de la siguiente manera:

RequiredErrorMessage -> "{0} es obligatorio".

donde {0} = mostrar nombre.

Luego anoto mis modelos de esta manera, para que nunca tenga que repetir las declaraciones de mis mensajes de error:

[RequiredWithMessage] public string Name { get; set; }

Una vez que haga esto, aparecerá un mensaje de error ("Se requiere nombre.") Siempre que la validación falle.

Esto funciona correctamente con la validación del lado del servidor de ASP.NET MVC y la validación del lado del cliente.


Podrías intentar hacer esto:

Agrega esta clase en algún lugar de tu proyecto:

public class ExternalResourceDataAnnotationsValidator : DataAnnotationsModelValidator<ValidationAttribute> { /// <summary> /// The type of the resource which holds the error messqages /// </summary> public static Type ResourceType { get; set; } /// <summary> /// Function to get the ErrorMessageResourceName from the Attribute /// </summary> public static Func<ValidationAttribute, string> ResourceNameFunc { get { return _resourceNameFunc; } set { _resourceNameFunc = value; } } private static Func<ValidationAttribute, string> _resourceNameFunc = attr => attr.GetType().Name; public ExternalResourceDataAnnotationsValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) : base(metadata, context, attribute) { if (Attribute.ErrorMessageResourceType == null) { this.Attribute.ErrorMessageResourceType = ResourceType; } if (Attribute.ErrorMessageResourceName == null) { this.Attribute.ErrorMessageResourceName = ResourceNameFunc(this.Attribute); } } }

y en su global.asax, agregue lo siguiente:

// Add once ExternalResourceDataAnnotationsValidator.ResourceType = typeof(CustomDataAnnotationsResources); // Add one line for every attribute you want their ErrorMessageResourceType replaced. DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RangeAttribute), typeof(ExternalResourceDataAnnotationsValidator));

Buscará una propiedad con el mismo nombre que el tipo de validador para el mensaje de error. Puede cambiar eso a través de la propiedad ResourceNameFunc.

EDIT: AFAIK esto funciona desde MVC2 en adelante, ya que DataAnnotationsModelValidatorProvider se introdujo en MVC2.