18

Es gibt eine Möglichkeit, die Standardressource für die Validierung der Datenanmerkungen festzulegen.Standardressource für Datenanmerkungen in ASP.NET MVC

Ich möchte nicht so etwas wie dies machen:

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

ich so etwas wie dies möchte:

Global.asax

DataAnnotations.DefaultResources = typeof(CustomDataAnnotationsResources); 

dann

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

jemand gimme ein Licht!

Dank im Voraus

EDIT

war mein eigentliches Problem mit EF-Code Ersten CTP4. CTP5 repariert es. Danke an alle.

+0

Kann jemand bitte Licht werfen, ob das möglich ist und wie sich diesem zu nähern. Vielen Dank. –

+0

werfen Sie einen Blick auf http://adamyan.blogspot.be/2010/02/aspnet-mvc-2-localization-complete.html Sie können die Liste der Standardnachrichten hier finden: http://stackoverflow.com/a/24186038/187650 – juFo

Antwort

13

Sie könnten versuchen, dies zu tun:

diese Klasse hinzufügen irgendwo in Ihrem Projekt:

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

und in Ihrer global.asax, fügen Sie folgendes:

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

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

Es sieht für eine Eigenschaft mit demselben Namen wie der Validierungstypen für die Fehlermeldung. Sie können dies über die ResourceNameFunc-Eigenschaft ändern.

EDIT: AFAIK das funktioniert von MVC2 ab, wie DataAnnotationsModelValidatorProvider in MVC2 eingeführt wurde.

+0

@CGK: Bitte werfen Sie auch einen Blick auf diese Frage.http: //stackoverflow.com/questions/4301218/decorate-model-fields-with-metadata-from-resource-file.Ich habe meine Anforderungen dort erklärt, obwohl ich platziert habe Ein Kopfgeld auf diese Frage –

+0

@conqenator: Beantwortete auch dort. – CGK

+0

das löste mein Problem perfekt, danke. –

12

Um dies zu erreichen, habe ich eine neue Klasse, die von RequiredAttribute erbt, und die Fehlermeldung innerhalb dieser neuen Klasse eingebettet:

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

Die Fehlermeldung von der ValidationResource.resx Datei aufgenommen wird, wo ich Liste die Fehlermeldung wie folgt auf:

RequiredErrorMessage -> "{0} ist erforderlich."

wobei {0} = Anzeigename.

ich dann meine Modelle wie diese mit Anmerkungen versehen, so habe ich nie Erklärungen meine Fehlermeldung wiederholen:

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

Sobald Sie dies tun, wird eine Fehlermeldung („Name erforderlich ist“) angezeigt wird, wenn die Validierung schlägt fehl.

Dies funktioniert ordnungsgemäß mit ASP.NET MVC serverseitige Validierung und clientseitige Validierung.

+0

Es funktioniert nicht !!! Diese Methode funktioniert beispielsweise für "DisplayNameAttribute", funktioniert aber nicht für "RequiredAttribute". Das macht mich verrückt :(Ich weiß nicht, was zu tun ist. –

+0

Amkh, das ist sehr bizarr. Es scheint für mich zu arbeiten. –

+0

Es funktioniert nur auf der Serverseite, weil es nicht generieren Daten-val-erforderlichen HTML-Attribut in MVC5 –

3

Ich habe einen anderen Ansatz. Sie müssen immer noch DataAnnotation Attribute erben, aber Sie können eine flexiblere Übersetzungslösung erhalten.

-Code aus my blog post (lesen Fore es mehr Details)

End Ergebnis

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 Inherit alle Datenaufbelichtung Attribute wie diese

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 Displayname

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. die Sprache Service erstellen (Sie können in es in jede beliebige Sprache Quelle wechseln)

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

Schließlich müssen Sie die String-Tabellen registrieren Sie verwenden, um die Überprüfungsmeldungen zu übersetzen und Ihre Modelle

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

+1 für die Freigabe dieses Codes. Ich habe noch nicht recht herausgefunden, wie man es benutzt (LoL), aber es scheint, dass es mein Problem lösen wird – ekkis