Pregunta

Estoy tratando de integrar NHibernate.Validator con ASP.NET MVC validaciones del lado del cliente, y el único problema que encontramos es que simplemente no puedo convertir el mensaje no interpolada a un ser legible por humanos. Pensé que esto sería una tarea fácil, pero resultó ser la parte más difícil de la validación del lado del cliente. El principal problema es que debido a que no es del lado del servidor, en realidad sólo necesita los atributos de validación que se están utilizando, y que en realidad no tienen una instancia o cualquier otra cosa a mano.

Aquí están algunos extractos de lo que he estado tratando ya:

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

Yo sé que lo anterior es un código bastante complejo para una pregunta aparentemente simple, pero todavía tengo que quedar sin solución. ¿Hay alguna manera de obtener la cadena interpolada de NHValidator?

¿Fue útil?

Solución

Ok, así que sé que esto es una vieja pregunta, pero me encontré con este cuando se trata de hacer lo mismo, y me ayudó a empezar -. Por lo que pensé que iba a dar una respuesta

Creo que el código en la pregunta estaba en el camino correcto pero hay un par de problemas. El interpolador no estaba completamente inicializado con los ResourceManager y Culture detalles, y no parece permitir el hecho de que sólo se puede tener uno DefaultMessageInterpolator por atributo de validación. Además, no se necesita una instancia del objeto que se está validando para obtener un mensaje de interpolada.

En el código de la pregunta, ¿dónde está inicializar el interpolador con el valor del atributo, también es necesario para inicializar el interpolador de datos de la ResourceManager a utilizar.

Esto se puede hacer utilizando el método Initialize sobrecargado en DefaultMessageInterpolator que tiene la siguiente firma:

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

El primer parámetro es un ResourceManager definida por el usuario en caso de que desee utilizar su propio archivo de recursos de mensajes de error, se puede pasar un valor nulo si lo que desea es utilizar el valor predeterminado ResouceManager, el segundo parámetro es el ResourceManager por defecto - que puede pasar

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

Para ello, el último parámetro es la cultura de uso, (NHibernate.Validator viene con archivos de recursos con mensajes de validación en varios idiomas) - si se pasa un valor nulo a este se acaba de utilizar CultureInfo.CurrentCulture

Por último, sólo se puede tener uno DefaultMessageInterpolator por atributo, por lo que tendrá que crear una nueva DefaultMessageInterpolator para cada atributo de validación. Se podría hacer uso de la DefaultMessageInterpolatorAggregator manejar esto, o simplemente rodar su propia cuenta.

Espero que esto ayude a alguien.

Otros consejos

Gracias por toda su ayuda - Me Upvote si pudiera. Sólo quería añadir que, además de la primera llamada de inicialización en la que DefaultMessageInterpolator Apestó ilustra, también tuve que realizar una segunda llamada de inicialización para inicializar diferente por completo (que estaba recibiendo algunas excepciones nulo de referencia utilizando sólo la primera llamada). Mi código es el siguiente:

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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top