views:

883

answers:

2

Has anyone managed to get a custom IMessageInterpolator working to enable customisation of error messages. I have tried following the instructions on this web page but to no avail. http://codelog.climens.net/2009/03/04/nhibernate-validator-custom-messages/

Looking into the code the DefaultMessageInterpolator seems pretty baked into the framework so is there anything I am missing.

I have included my unit tests to show how I am implementing it.

namespace TestValidator
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestValidator()
        {
            var customer = new Customer();

            ClassValidator classValidator = new ClassValidator(customer.GetType());
            InvalidValue[] validationMessages = classValidator.GetInvalidValues(customer);

            Assert.IsTrue(validationMessages.Length == 1);
            Assert.IsTrue(validationMessages[0].Message == "may not be null or empty");
        }

        [TestMethod]
        public void TestCustomInterpolator()
        {
            ValidatorEngine ve = new ValidatorEngine();
            NHVConfiguration nhvc = new NHVConfiguration();
            nhvc.Properties[Environment.MessageInterpolatorClass] = typeof(CustomMessageInterpolator).AssemblyQualifiedName;
            ve.Configure(nhvc);

            var customer = new Customer();

            ClassValidator classValidator = new ClassValidator(customer.GetType());
            InvalidValue[] validationMessages = classValidator.GetInvalidValues(customer);

            Assert.IsTrue(validationMessages.Length == 1);
            // THIS TEST FAILS!!
            Assert.IsTrue(validationMessages[0].Message == "CustomMessageInterpolator");
        }
    }

    public class Customer
    {
        public virtual int CustomerId { get; set; }

        [NotNullNotEmpty]
        public string CustomerName { get; set; }
    }

    public class CustomMessageInterpolator : IMessageInterpolator
    {
        public CustomMessageInterpolator()
        {

        }

        public string Interpolate(string message, IValidator validator, IMessageInterpolator defaultInterpolator)
        {
            return "CustomMessageInterpolator";
        }
    }
}
A: 

I looked over your problem and the most interesting is that:

Assert.AreEqual(typeof(CustomMessageInterpolator), ve.Interpolator.GetType());

is true. I assume the problem is in the fact that CFG was already configured with DefaultMessageInterpolator, and the

ve.Configure(nhvc);

does not have the effect, because ClassValidator uses nomatter of this configuration the DefaultMessageInterpolator. This is the cause why for Climens, it worked in App.config, not in nhvalidator.cfg.xml.

diadiora
+1  A: 

I have got this to work finally. Before calling the validator in my repository I explicitly create and pass the Interpolator as a parameter.

ClassValidator classValidator = new ClassValidator(obj.GetType(), null, new CustomMessageInterpolator(), 
CultureInfo.CurrentCulture, ValidatorMode.UseAttribute);
InvalidValue[] validationMessages = classValidator.GetInvalidValues(obj);
Craig