Frage

Ich versuche NHibernate.Validator mit ASP.NET MVC Client-Seite Validierungen zu integrieren, und das einzige Problem, fand ich, dass ich einfach nicht die nicht-interpolierte Nachricht an einem Menschen lesbaren umwandeln kann. Ich dachte, dies wäre eine leichte Aufgabe sein, aber stellte sich heraus, ist der schwierigste Teil des clientseitige Validierung zu sein. Das Hauptproblem besteht darin, dass, weil es nicht serverseitige, ich eigentlich nur die Validierungs Attribute müssen, die verwendet werden, und ich weiß nicht wirklich eine Instanz oder irgendetwas anderes zur Hand haben.

Hier sind einige Auszüge aus dem, was ich habe schon versucht:

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

Ich weiß, dass die oben ist ein ziemlich komplexer Code für eine scheinbar einfache Frage, aber ich bin immer noch ohne Lösung stecken. Gibt es eine Möglichkeit, die interpolierten Zeichenfolge aus NHValidator zu bekommen?

War es hilfreich?

Lösung

Ok, damit ich weiß, das ist eine alte Frage, aber ich über diese gestolpert, wenn die gleiche Sache zu tun versucht, und es hat mir geholfen, loszulegen -. So dass ich dachte, ich würde eine Antwort geben

Ich denke, der Code in der Frage auf dem richtigen Weg war, aber es gibt ein paar Probleme. Der Interpolator wurde nicht vollständig mit den ResourceManager und Culture Details initialisiert, und es scheint nicht für die Tatsache zu berücksichtigen, dass Sie nur eine DefaultMessageInterpolator pro Validierung Attribut haben können. Auch Sie nicht über eine Instanz des Objekts müssen Sie die Validierung eine interpolierte Nachricht zu erhalten.

Im Code in der Frage, wo Sie den Interpolator mit dem Attributwert werden initialisiert, können Sie auch den Interpolator mit Details der ResourceManager müssen zur Initialisierung verwendet werden.

Dies kann mit der überladenen Initialize Methode auf DefaultMessageInterpolator erfolgen, die die folgende Signatur hat:

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

Der erste Parameter eine benutzerdefinierte Resourcemanager in Fall Sie Ihre eigene Ressource-Datei für Fehlermeldungen verwenden, können Sie eine null übergeben, wenn Sie nur die Standard-ResouceManager verwenden möchten, ist der zweite Parameter der Standard-Resourcemanager - Sie passieren kann

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

für diese, der letzten Parameter die Kultur verwendet wird, (NHibernate.Validator kommt mit Ressourcendateien mit Überprüfungsmeldungen in mehreren Sprachen) - wenn Sie eine Null, um diese passieren wird es nur verwenden CultureInfo.CurrentCulture

Schließlich können Sie nur eine DefaultMessageInterpolator pro Attribut, so dass Sie eine neue DefaultMessageInterpolator für jede Validierung Attribut erstellen müssen. Sie könnten die Verwendung des DefaultMessageInterpolatorAggregator machen, dies zu umgehen, oder einfach nur Ihre eigene Rolle.

Ich hoffe, das jemand hilft.

Andere Tipps

Danke für Ihre Hilfe all - Id upvote wenn ich könnte. Ich wollte nur, dass auf dem DefaultMessageInterpolator zum ersten Initialisieren Anruf zusätzlich hinzufügen, dass Stinken zeigt, musste ich auch einen zweiten unterschiedlichen initialisieren Anruf, um es vollständig zu initialisieren (ich war einige Null Referenz Ausnahmen immer nur den ersten Anruf verwenden). Mein Code ist wie folgt:

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);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top