Question

Je suis en train d'intégrer NHibernate.Validator avec ASP.NET MVC côté validation client, et le seul problème que j'ai trouvé est que je ne peux tout simplement pas convertir le message non-interpolée à un lisible par l'homme. Je pensais que ce serait une tâche facile, mais avéré être le plus dur de la validation côté client. Le principal problème est que parce qu'il est pas côté serveur, en fait je seulement besoin des attributs de validation qui sont utilisés, et je n'ai pas réellement une instance ou toute autre chose à portée de main.

Voici quelques extraits de ce que j'ai déjà essayé:

// Get the the default Message Interpolator from the Engine
IMessageInterpolator interp = _engine.Interpolator;
if (interp == null)
{
  // It is null?? Oh, try to create a new one
  interp = new NHibernate.Validator.Interpolator.DefaultMessageInterpolator();
}

// We need an instance of the object that needs to be validated, se we have to create one
object instance = Activator.CreateInstance(Metadata.ContainerType);

// we enumerate all attributes of the property. For example we have found a PatternAttribute
var a = attr as PatternAttribute;

// it seems that the default message interpolator doesn't work, unless initialized
if (interp is NHibernate.Validator.Interpolator.DefaultMessageInterpolator)
{
  (interp as NHibernate.Validator.Interpolator.DefaultMessageInterpolator).Initialize(a);
}

// but even after it is initialized the following will throw a NullReferenceException, although all of the parameters are specified, and they are not null (except for the properties of the instance, which are all null, but this can't be changed)
var message = interp.Interpolate(new InterpolationInfo(Metadata.ContainerType, instance, PropertyName, a, interp, a.Message));

Je sais que ce qui précède est un code assez complexe pour une question apparemment simple, mais je suis toujours bloqué sans solution. Est-il possible d'obtenir la chaîne interpolée de NHValidator?

Était-ce utile?

La solution

Ok, donc je sais que c'est une vieille question, mais je suis tombé sur ce en essayant de faire la même chose, et il m'a aidé à démarrer -. Donc je pensais que je fournirais une réponse

Je pense que le code dans la question était sur la bonne voie, mais il y a quelques problèmes. Le interpolateur n'a pas été complètement initialisés avec les détails de ResourceManager et Culture, et il ne semble pas tenir compte du fait que vous ne pouvez avoir qu'un seul DefaultMessageInterpolator par attribut de validation. En outre, vous n'avez pas besoin d'une instance de l'objet que vous validez pour obtenir un message interpolée.

Dans le code dans la question, où vous l'interpolateur avec INITIALISATION la valeur d'attribut, vous avez également besoin d'initialiser le interpolateur avec des détails de la ResourceManager à utiliser.

Cela peut être fait en utilisant la méthode de Initialize surcharge sur DefaultMessageInterpolator qui a la signature suivante:

    public void Initialize(ResourceManager messageBundle, 
                           ResourceManager defaultMessageBundle, 
                           CultureInfo culture)

Le premier paramètre est un ResourceManager défini par l'utilisateur dans le cas où vous souhaitez utiliser votre propre fichier de ressources pour les messages d'erreur, vous pouvez passer un null si vous voulez juste utiliser la valeur par défaut ResouceManager, le second paramètre est la valeur par défaut ResourceManager - vous peut passer

  new ResourceManager( 
      NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
      Assembly.GetExecutingAssembly());

pour cela, le dernier paramètre est la culture à utiliser, (NHibernate.Validator est livré avec les fichiers de ressources avec des messages de validation en plusieurs langues) - si vous passez un nul pour cela, il va simplement utiliser CultureInfo.CurrentCulture

Enfin, vous ne pouvez avoir un DefaultMessageInterpolator par attribut, vous devez créer une nouvelle DefaultMessageInterpolator pour chaque attribut de validation. Vous pouvez utiliser la DefaultMessageInterpolatorAggregator pour gérer cela, ou tout simplement rouler votre propre.

J'espère que cela aide quelqu'un.

Autres conseils

Merci pour votre aide tous - si je Upvote Id pouvais. Je voulais juste ajouter que, en plus du premier appel Initialiser sur le DefaultMessageInterpolator que Stank illustre, je devais aussi faire un second appel différent Initialize pour initialiser complètement (je recevais des exceptions Null référence en utilisant uniquement le premier appel). Mon code est le suivant:

string interpolatedMessage = "";
DefaultMessageInterpolator interpolator = new DefaultMessageInterpolator();

interpolator.Initialize(null,
    new ResourceManager(
        NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
        Assembly.Load("NHibernate.Validator")),
        CultureInfo.CurrentCulture);

interpolator.Initialize(attribute as Attribute);

if (attribute is IValidator && attribute is IRuleArgs)
{
    IValidator validator = attribute as IValidator;
    IRuleArgs ruleArgs = attribute as IRuleArgs;

    InterpolationInfo interpolationInfo = new InterpolationInfo(
        validatableType, 
        null, 
        propertyName, 
        validator,
        interpolator, 
        ruleArgs.Message);

    interpolatedMessage = interpolator.Interpolate(interpolationInfo);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top