ASP.NET MVC: messaggio di convalida personalizzato per i tipi di valore

Quando utilizzo UpdateModel o TryUpdateModel, il framework MVC è abbastanza intelligente da sapere se si sta tentando di trasferire un valore null in un tipo di valore (ad esempio, l’utente dimentica di compilare il campo Giorno di nascita richiesto).

Sfortunatamente, non so come sovrascrivere il messaggio predefinito, “È richiesto un valore.” nel sumrio in qualcosa di più significativo (“Per favore, inserisci il tuo giorno di nascita”).

Deve esserci un modo per farlo (senza scrivere troppo codice di aggiramento), ma non riesco a trovarlo. Qualsiasi aiuto?

MODIFICARE

Inoltre, immagino che questo sarebbe anche un problema per le conversioni non valide, ad esempio BirthDay = “Ciao”.

Crea il tuo ModelBinder estendendo DefaultModelBinder:

public class LocalizationModelBinder : DefaultModelBinder 

Sostituisci SetProperty:

  base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value); foreach (var error in bindingContext.ModelState[propertyDescriptor.Name].Errors. Where(e => IsFormatException(e.Exception))) { if (propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)] != null) { string errorMessage = ((TypeErrorMessageAttribute)propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)]).GetErrorMessage(); bindingContext.ModelState[propertyDescriptor.Name].Errors.Remove(error); bindingContext.ModelState[propertyDescriptor.Name].Errors.Add(errorMessage); break; } } 

Aggiungere la funzione bool IsFormatException(Exception e) per verificare se un’eccezione è un FormatException:

 if (e == null) return false; else if (e is FormatException) return true; else return IsFormatException(e.InnerException); 

Crea una class di attributi:

 [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] public class TypeErrorMessageAttribute : Attribute { public string ErrorMessage { get; set; } public string ErrorMessageResourceName { get; set; } public Type ErrorMessageResourceType { get; set; } public TypeErrorMessageAttribute() { } public string GetErrorMessage() { PropertyInfo prop = ErrorMessageResourceType.GetProperty(ErrorMessageResourceName); return prop.GetValue(null, null).ToString(); } } 

Aggiungi l’attributo alla proprietà che desideri convalidare:

 [TypeErrorMessage(ErrorMessageResourceName = "IsGoodType", ErrorMessageResourceType = typeof(AddLang))] public bool IsGood { get; set; } 

AddLang è un file resx e IsGoodType è il nome della risorsa.

E infine aggiungilo in Global.asax.cs Application_Start:

 ModelBinders.Binders.DefaultBinder = new LocalizationModelBinder(); 

Saluti!

Con DefaultModelBinder è ansible sovrascrivere il messaggio di errore predefinito richiesto, ma sfortunatamente si applicherà a livello globale che IMHO lo rende completamente inutile. Ma se decidi di farlo, ecco come:

  1. Aggiungi la cartella App_GlobalResources al tuo sito ASP.NET
  2. Aggiungi un file di risorse chiamato Messages.resx
  3. All’interno del file delle risorse dichiarare una nuova risorsa stringa con la PropertyValueRequired e un valore
  4. In Application_Start aggiungi la seguente riga:

     DefaultModelBinder.ResourceClassKey = "Messages"; 

Come puoi vedere, non esiste alcun collegamento tra la proprietà del modello che stai convalidando e il messaggio di errore.

In conclusione, è meglio scrivere una logica di convalida personalizzata per gestire questo scenario. Un modo sarebbe utilizzare un tipo nullable (System.Nullable ) e quindi:

 if (model.MyProperty == null || /** Haven't tested if this condition is necessary **/ !model.MyProperty.HasValue) { ModelState.AddModelError("MyProperty", "MyProperty is required"); } 

Ho usato il fantastico framework di convalida xVal . Mi consente di eseguire tutte le convalide nel modello (anche LINQ-SQL :)). Emette anche il javascript richiesto per la validazione lato client.

EDIT: Scusa lasciato fuori il link per come farlo funzionare per LINQ-SQL

Il stream di lavoro di base è simile a questo.

 public partial class YourClass { [Required(ErrorMessage = "Property is required.")] [StringLength(200)] public string SomeProperty{ get; set; } } 

 try { // Validate the instance of your object var obj = new YourClass() { SomeProperty = "" } var errors = DataAnnotationsValidationRunner.GetErrors(obj); // Do some more stuff eg Insert into database } catch (RulesException ex) { // eg control name 'Prefix.Title' ex.AddModelStateErrors(ModelState, "Prefix"); ModelState.SetModelValue("Prefix.Title", new ValueProviderResult(ValueProvider["Prefix.Title"].AttemptedValue, collection["Prefix.Title"], System.Globalization.CultureInfo.CurrentCulture)); } 

cosa ne pensi di questo?

 [RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$", ErrorMessage = "Characters are not allowed.")] 

Ciò dovrebbe consentire di taggare le proprietà con specifici messaggi di errore per qualunque validatore MVC che si desidera utilizzare …

In ASP.NET MVC 1, ho incontrato anche questo problema.

Nel mio progetto, c’è un modello o un object business chiamato “Entry”, e la sua chiave primaria EntryId è int? digita, e il valore di EntryId può essere permesso dagli utenti.

Quindi il problema è che quando il campo è vuoto o zero o qualche valore intero che è esistito, i messaggi di errore personalizzati possono essere mostrati bene, ma se il valore è un valore non intero come “a”, non riesco a trovare un modo utilizzare il messaggio personalizzato per sostituire il messaggio predefinito come “Il valore ‘a’ non è valido”.

quando rintraccio il messaggio di errore in ModelState, ho trovato quando il valore non è intero, ci saranno due errori relativi a EntryId e il messaggio di errore del primo elemento è vuoto …

Ora devo usare un codice così brutto per violare il problema.

 if (ModelState["EntryId"].Errors.Count > 1) { ModelState["EntryId"].Errors.Clear(); //should not use ModelState["EntryId"].remove(); ModelState.AddModelError("EntryId", "必须为大于0的整数"); //必须为大于0的整数 means "it should be an integer value and great than 0" } 

ma questo rende il controller grasso, spero che ci sia una vera soluzione per risolverlo.

Cercare ModelState.AddError .

sì, c’è un modo, è necessario utilizzare System.ComponentModel.DataAnnotations in combinazione con xVal e si sarà in grado di impostare regole e messaggi di convalida (si può anche usare i file di risorse per la localizzazione) per ciascuna proprietà usando Attributi
guarda qui http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/