2010-01-12 3 views
2

Il semble y avoir quelque chose d'un trou dans la façon dont DataAnnotations fonctionne en ce qu'un utilisateur entre un texte dans un champ qui va dans un int n'atteindra jamais le code DataAnnotations. Il déclenche une erreur de liaison de modèle et affiche l'erreur à l'utilisateur "La valeur 'a' n'est pas valide pour le champ XXXX."ASP.NET MVC: DataAnnotations - Afficher un message d'erreur indiquant qu'un champ doit être numérique

Quoi qu'il en soit, tout est très bien qu'il gère automatiquement cette situation, mais je veux vraiment afficher un message d'erreur indiquant le problème, par exemple. "La valeur 'a' n'est pas numérique Veuillez entrer une valeur numérique pour le champ XXXX". J'ai essayé les solutions How to replace the default ModelState error message in Asp.net MVC 2? et ASP.NET MVC - Custom validation message for value types, mais je ne peux pas les faire fonctionner.

Il semble que mon fichier de ressources ne soit pas lu du tout, car ici (http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultmodelbinder.resourceclasskey.aspx) il indique "Si la propriété est définie sur une clé de classe invalide (comme un fichier de ressources qui n'existe pas), MVC lance un exception." et même si je change la ligne à DefaultModelBinder.ResourceClassKey = "asdfasdhfk" il n'y a aucune exception.

Vous avez des idées?

EDIT: Voici du code. Tout cela fonctionne moins mes messages du fichier Messages.resx ne sont pas utilisés. Le code pour Messages.resx est généré automatiquement, donc je ne l'inclurai pas.

L'entrée de "a" dans ProcessOrder résulte en un message générique plutôt que ce que j'ai entré dans Messages.resx pour PropertyValueInvalid (et InvalidPropertyValue pour une bonne mesure).

méthode Application_Start

protected void Application_Start() 
{    
    RegisterRoutes(RouteTable.Routes); 
    ModelBinders.Binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder(); //set dataanooations to be used 
    DefaultModelBinder.ResourceClassKey = "Messages"; //set data annotations to look in messages.resx for the default messages 
    ValidationExtensions.ResourceClassKey = "Messages"; 
} 

Entité Classe

[MetadataType(typeof(GLMetaData))] 
public partial class GL 
{ 

} 



public class GLMetaData 
{ 
    public int TransRefId { get; set; } 

    [DisplayName("Process Order")] 
    public int? ProcessOrder { get; set; } 

    [DisplayName("Trans Type")] 
    [StringLength(50)] 
    public string TransType { get; set; } 

    [StringLength(100)] 
    public string Description { get; set; } 

    [DisplayName("GL Code")] 
    [StringLength(20)] 
    public string GLCode { get; set; } 

    [DisplayName("Agents Credit No")] 
    [StringLength(50)] 
    public string AgentsCreditNo { get; set; } 

    [Required] 
    public bool Active { get; set; } 
} 

Action Controller:

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Edit(GL glToBeUpdated) 
    { 
     try 
     { 
      if (!ModelState.IsValid) 
       return View(glToBeUpdated); 

      //set auto properties 
      glToBeUpdated.UpdateDate = DateTime.Now; 
      glToBeUpdated.UpdateUser = this.CurrentUser; 

      glDataLayer.update(glToBeUpdated); 

      glDataLayer.submitChanges(); 

      return RedirectToAction("Index"); 
     } 
     catch 
     { 
      glDataLayer.abortChanges(); 

      throw; 
     } 
    } 
+0

code pour nous de passer en revue? –

+0

L'avez-vous fait fonctionner? Même problème ici ... – Etienne

+0

Non. Je suis passé principalement à la validation côté client (principalement via le plugin jquery alphanumeric) avec la validation côté serveur dans le backend sans les messages d'erreur entièrement descriptifs comme solution de repli. Les utilisateurs de ce système sont tous internes à mon entreprise et je peux m'assurer qu'ils ont toujours le javascript activé, donc la validation back-end est juste une mesure de sécurité, donc pas besoin de jolis messages d'erreur. – Alistair

Répondre

1

Ce que je l'ai fait pour lutter contre un problème similaire était de dégager l'état du modèle, valider contre ModelState["XXXX"].Value.AttemptedValue au lieu de contre la valeur annulée causée par un essayant de mettre un dans valeur valide dans la propriété du modèle, remplissant les messages d'erreur et réinitialisant les valeurs du modèle.

De cette façon, je peux avoir les messages d'erreur que je veux et, le cas échéant, en offrir plus d'un ("une valeur est requise" ou "la valeur doit être numérique").

+0

Intéressant, cependant la validation DataAnnotations n'est pas du tout atteinte donc je ne peux pas utiliser cette méthode. J'ai décidé d'utiliser le plugin jquery alphanumeric pour empêcher la saisie de données non-numériques. Vous pouvez toujours passer cette validation dans certains cas, mais dans l'ensemble, la solution est assez bonne. – Alistair

0
+0

Essayé de cette façon, mais ça ne fonctionnait pas. – Alistair

+0

essayez ce lien: http://stackoverflow.com/questions/1538873/how-to-replace-the-default-modelstate-error-message-in-asp-net-mvc-2/1540874#1540874 et remplacez InvalidPropertyValue par PropertyValueInvalid si vous utilisez asp.net mvc 2 rc. –

0

Je lutté contre pour la plupart de la journée sur MVC4 RC. Peu importe ce que j'ai mis

DefaultModelBinder.ResourceClassKey 

à cela n'a jamais semblé fonctionner. Il n'a également jamais jeté une exception quand j'ai assigné indésirable.

C'est ce que j'utilisais pour affecter la valeur (sans succès):

DefaultModelBinder.ResourceClassKey = typeof(App_GlobalResources.ValidationMessages).Name; 

En fin de compte, j'ai décidé d'aborder ce message d'erreur sur le côté client et remplacer les attributs de données que jQuery utilise pour afficher le message.

@Html.TextBoxFor(m => m.Amount, new Dictionary<string,object>(){{"data-val-number","Invalid Number"}}) 

Cela fonctionne comme j'en ai besoin.

Ironiquement ceci fonctionne aussi:

@Html.TextBoxFor(m => m.Amount, new Dictionary<string, object>() {{ "data-val-number", HttpContext.GetGlobalResourceObject("ValidationMessages", "PropertyValueInvalid") } }) 
0

Ici, je prends contact numéro champ sous forme de chaîne, mais avec Attribut de plage peut donc fournir validatioin numérique à utiliser si à partir de votre fichier de ressources.

[Required(ErrorMessageResourceType = typeof(Global), ErrorMessageResourceName = "ContactNumberRequired")] 
    [Range(0, int.MaxValue, ErrorMessageResourceType = typeof(Global), ErrorMessageResourceName = "ValidContactNumber")] 
    [Display(Name = "Contact Number")] 
    public string ContactNumber { get; set; } 

Donc maintenant fourni ErrorMessageResourceName comme clé. Vous pouvez le personnaliser et l'utiliser également en Multi Language

Questions connexes