Ressource par défaut pour les annotations de données dans ASP.NET MVC

il y a un moyen de définir la ressource par défaut aux annotations de données validations?

je ne veux pas faire quelque chose comme ceci:

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

j'aimerais faire quelque chose comme ceci:

Global.asax

DataAnnotations.DefaultResources = typeof(CustomDataAnnotationsResources);

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

quelqu'un donne-moi un peu!

merci d'avance

EDIT

mon vrai problème était avec le code EF D'abord CTP4. CTP5 répare ça. Merci pour chacun.

18
demandé sur Kim Tranjan 2010-07-16 03:04:59

3 réponses

Vous pourriez essayer de faire ceci:

 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);
        }
    }
}

et dans votre global.asax, ajoutez la ligne suivante:

// Add once
ExternalResourceDataAnnotationsValidator.ResourceType = typeof(CustomDataAnnotationsResources);

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

il recherchera une propriété avec le même nom que le type de validateur pour le message d'erreur. Vous pouvez changer cela via la propriété ResourceNameFunc.

EDIT: AFAIK cela fonctionne à partir de MVC2, car DataAnnotationsModelValidatorProvider a été introduit dans MVC2.

13
répondu CGK 2010-12-03 12:59:25

pour y parvenir, j'ai créé une nouvelle classe qui hérite de RequiredAttribute, et le message d'erreur est intégré dans cette nouvelle classe:

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

le message d'erreur est tiré de ValidationResource.fichier resx, où je liste le message d'erreur comme suit:

Requerderrormessage -- > " {0} is required."

{0} = nom d'affichage.

j'annote alors mes modèles comme ça, donc je n'ai jamais à répéter mon message d'erreur déclarations:

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

une fois que vous avez fait ceci, un message d'erreur ("Name is required.") apparaîtra chaque fois que la validation échoue.

cela fonctionne correctement avec ASP.NET la validation côté serveur et la validation côté client de MVC.

12
répondu Johnny Oshika 2010-12-08 07:33:12

j'ai fait une autre approche. Il a encore besoin de vous pour hériter DataAnnotation attributs, mais vous pouvez obtenir une solution de traduction plus flexible.

Code de mon billet de blog (lire pour plus de détails)

résultat

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 hériter de tous les attributs d'annotation de données comme ceci

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 Inherit 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. Créer l' service de langue (vous pouvez passer à n'importe quelle source de langue)

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;
    }
}

enfin vous devez enregistrer les tables de string que vous utilisez pour traduire les messages de validation et vos modèles

LanguageService.Instance.Add(MyNameSpace.ModelResource.ResourceManager);
LanguageService.Instance.Add(MyNameSpace.ValidationResources.ResourceManager);
3
répondu jgauffin 2010-12-03 13:13:40