简体   繁体   English

nHibernate验证程序自定义IMessageInterpolator

[英]nHibernate Validator custom IMessageInterpolator

Has anyone managed to get a custom IMessageInterpolator working to enable customisation of error messages. 有没有人设法让自定义IMessageInterpolator能够启用自定义错误消息。 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/ 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. 查看代码,DefaultMessageInterpolator看起来已经很好地融入了框架,所以我缺少什么了。

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";
        }
    }
}

I have got this to work finally. 我终于有了这个工作。 Before calling the validator in my repository I explicitly create and pass the Interpolator as a parameter. 在我的存储库中调用验证器之前,我会明确创建并传递Interpolator作为参数。

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

I am using fluent Nhibernate to register the NHibernate validator and the Message interpolator is integrated correctly. 我正在使用流畅的Nhibernate注册NHibernate验证器,并且消息插值器已正确集成。 The key to remember is that the Shared Engine Provider provides Singleton access to the Validator Engine. 要记住的关键是共享引擎提供程序提供对验证器引擎的单例访问。 If you try to instantiate a new validator Engine in your application, it will not have the message interpolator configured as the only way to configure it is during initialization as demonstrated below. 如果您尝试在应用程序中实例化一个新的验证器引擎,它将不会配置消息内插器,因为配置它的唯一方法是在初始化期间,如下所示。

        Environment.SharedEngineProvider = new NHibernateSharedEngineProvider();

        var fluentConfiguration = new FluentConfiguration();

        fluentConfiguration
            .SetMessageInterpolator<CustomMessageInterpolator>()
            .SetDefaultValidatorMode(ValidatorMode.OverrideAttributeWithExternal)
            .IntegrateWithNHibernate
            .ApplyingDDLConstraints()
            .And
            .RegisteringListeners();

        var validatorEngine = Environment.SharedEngineProvider.GetEngine();
        validatorEngine.Configure(fluentConfiguration);
        configuration.Initialize(validatorEngine);

If you require a validator to check an entity at runtime, instead of creating a new instance of the validator, you can request a validator from the engine you registered when configuring NHV. 如果需要验证程序在运行时检查实体,而不是创建验证程序的新实例,则可以在配置NHV时从注册的引擎请求验证程序。

var engine = NHibernate.Validator.Cfg.Environment.SharedEngineProvider.GetEngine();
return engine.GetClassValidator(YourEntityType);

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 我认为问题是因为CFG已经使用DefaultMessageInterpolator配置,并且

ve.Configure(nhvc);

does not have the effect, because ClassValidator uses nomatter of this configuration the DefaultMessageInterpolator. 这没有效果,因为ClassValidator使用此配置的nomatter DefaultMessageInterpolator。 This is the cause why for Climens, it worked in App.config, not in nhvalidator.cfg.xml. 这就是为什么Climens在App.config中而不是在nhvalidator.cfg.xml中起作用的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM