MVC: Sostituisci ValidationMessage predefinito
-
05-07-2019 - |
Domanda
Nel mondo di MVC ho questo modello di visualizzazione ...
public class MyViewModel{
[Required]
public string FirstName{ get; set; } }
... e questo genere di cose a mio avviso ...
<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<%= Html.TextBox("FirstName") %>
<%= Html.ValidationMessage("FirstName", "*") %>
La mia domanda: se invio questo modulo senza fornire un nome, ricevo il seguente messaggio " Il campo FirstName è obbligatorio "
OK. Quindi, vado e cambio la mia proprietà in ...
[DisplayName("First Name")]
[Required]
public string FirstName{ get; set; }
..e ora ottieni " Il campo Nome è obbligatorio "
Finora tutto bene.
Quindi ora voglio che il messaggio di errore visualizzi " Nome Blah Blah " ;. Come posso sovrascrivere il messaggio predefinito per visualizzare DisplayName + " Blah Blah " ;, senza annotare tutte le proprietà con qualcosa come
[Required(ErrorMessage = "First Name Blah Blah")]
Saluti,
ETFairfax
Soluzione
public class GenericRequired: RequiredAttribute
{
public GenericRequired()
{
this.ErrorMessage = "{0} Blah blah";
}
}
Altri suggerimenti
Ecco un modo per farlo senza sottoclassare RequiredAttribute
. Basta creare alcune classi dell'adattatore di attributi. Qui sto usando ErrorMessageResourceType
/ ErrorMessageResourceName
(con una risorsa) ma potresti facilmente impostare ErrorMessage
, o addirittura verificare l'esistenza di sostituzioni prima impostando questi.
Global.asax.cs:
public class MvcApplication : HttpApplication {
protected void Application_Start() {
// other stuff here ...
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(RequiredAttribute), typeof(CustomRequiredAttributeAdapter));
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(StringLengthAttribute), typeof(CustomStringLengthAttributeAdapter));
}
}
private class CustomRequiredAttributeAdapter : RequiredAttributeAdapter {
public CustomRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
: base(metadata, context, attribute)
{
attribute.ErrorMessageResourceType = typeof(Resources);
attribute.ErrorMessageResourceName = "ValRequired";
}
}
private class CustomStringLengthAttributeAdapter : StringLengthAttributeAdapter {
public CustomStringLengthAttributeAdapter(ModelMetadata metadata, ControllerContext context, StringLengthAttribute attribute)
: base(metadata, context, attribute)
{
attribute.ErrorMessageResourceType = typeof(Resources);
attribute.ErrorMessageResourceName = "ValStringLength";
}
}
In questo esempio è necessario creare un file di risorse denominato Resources.resx con ValRequired
come nuovo messaggio predefinito richiesto e ValStringLength
poiché la lunghezza della stringa ha superato il messaggio predefinito. Nota che per entrambi, {0}
riceve il nome del campo, che puoi impostare con [Display (Nome = " Nome campo ")]
.
Sembra che RequiredAttribute non implementa IClientValidatable, quindi se si sovrascrive il RequiredAttribute si interrompe la convalida lato client.
Quindi questo è quello che ho fatto e funziona. Spero che questo aiuti qualcuno.
public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
public CustomRequiredAttribute()
{
this.ErrorMessage = "whatever your error message is";
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessage,
ValidationType = "required"
};
}
}
Basta cambiare
[Required]
a
[Required(ErrorMessage = "Your Message, Bla bla bla aaa!")]
Modifica: l'ho pubblicato perché stavo cercando questa soluzione con l'attributo [Richiesto] e ho avuto problemi a trovarla. La creazione di nuovi Q / A non sembra così buona, poiché questa domanda esiste già.
Stavo cercando di risolvere la stessa cosa e ho trovato una soluzione molto semplice in MVC 4.
Innanzitutto, probabilmente dovresti archiviare i messaggi di errore in qualche posto. Ho usato risorse personalizzate, ben descritte in http://afana.me/post/aspnet-mvc -internationalization.aspx.
È importante poter ottenere qualsiasi risorsa (anche un messaggio di errore) semplicemente chiamando ResourcesProject.Resources.SomeCustomError o ResourcesProject.Resources.MainPageTitle ecc. Ogni volta che provo per accedere alla classe Risorse, prende le informazioni sulla cultura dal thread corrente e restituisce la lingua corretta.
Ho un messaggio di errore per la convalida del campo in ResourcesProject.Resources.RequiredAttribute . Per impostare questo messaggio affinché appaia in Visualizza, aggiorna semplicemente l'attributo [Richiesto] con questi due parametri.
ErrorMessageResourceType - Tipo che verrà chiamato (nel nostro esempio ResourcesProject.Resources)
ErrorMessageResourceName - Proprietà, che verrà chiamata sul tipo sopra (nel nostro caso RequiredAttribute)
Ecco un modello di accesso molto semplificato, che mostra solo un messaggio di convalida del nome utente. Quando il campo è vuoto, prenderà la stringa da ResourcesProject.Resources.RequiredAttribute e lo visualizzerà come un errore.
public class LoginModel
{
[Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName="RequiredAttribute")]
[Display(Name = "User name")]
public string UserName { get; set; }
}
Puoi scrivere il tuo attributo:
public class MyRequiredAttribute : ValidationAttribute
{
MyRequiredAttribute() : base(() => "{0} blah blah blah blaaaaaah")
{
}
public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
string str = value as string;
if (str != null)
{
return (str.Trim().Length != 0);
}
return true;
}
}
Questa è una copia di RequiredAttribute da Reflector con un messaggio di errore modificato.
using Resources;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Web;
using System.Web.Mvc;
public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
public CustomRequiredAttribute()
{
ErrorMessageResourceType = typeof(ValidationResource);
ErrorMessageResourceName = "RequiredErrorMessage";
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = GetRequiredMessage(metadata.DisplayName),
ValidationType = "required"
};
}
private string GetRequiredMessage(string displayName) {
return displayName + " " + Resources.ValidationResource.RequiredErrorMessageClient;
}
}
App_GlobalResources / ValidationResource.resx
Ora usa l'annotazione dei dati
[CustomRequired]
Questo ha funzionato per me. Leggi attentamente i commenti all'interno del codice. (Basato sulla risposta del Ciad).
// Keep the name the same as the original, it helps trigger the original javascript
// function for client side validation.
public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute, IClientValidatable
{
public RequiredAttribute()
{
this.ErrorMessage = "Message" // doesnt get called again. only once.
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = "Message", // this gets called on every request, so it's contents can be dynamic.
ValidationType = "required"
};
}
}