我想NHibernate.Validator与ASP.NET MVC客户端验证整合,而且我发现唯一的问题是我根本无法转换非插值消息到人类可读的一个。我认为这将是一件容易的事,但竟然是在客户端验证中最难的部分。主要的问题是,因为它不是服务器端,我实际上只需要一个正在使用的验证属性,我实际上没有一个实例或手头其他任何东西。

下面是从我已经已经开始尝试一些摘录:

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

我知道上面是一个看似简单的问题相当复杂的代码,但我仍然坚持没有解决之道。有没有什么办法让插值串出NHValidator的?

有帮助吗?

解决方案

好了,我知道这是一个老问题,但我碰到这个偶然试图做同样的事情时,它帮助我上手 - 所以我想我会提供一个答案

我觉得在这个问题的代码是在正确的轨道上,但也有几个问题。内插器没有完全与ResourceManagerCulture细节初始化,它似乎并没有允许的事实,你只能有每个验证一个属性DefaultMessageInterpolator。此外,你不需要你验证获得的插补消息对象的实例。

在问题中,在这里与属性值初始化所述内插器的代码,则还需要初始化与ResourceManager的细节的内插中使用。

这可以使用具有以下签名上Initialize重载DefaultMessageInterpolator方法完成的:

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

第一个参数是用户定义的ResourceManager中要使用的错误消息您自己的资源文件的情况下,你可以传递一个空,如果你只是想使用默认ResouceManager,第二个参数是默认的ResourceManager - 你可以通过

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

对于这一点,最后一个参数是文化的使用,(NHibernate.Validator配备了带几种语言的验证消息的资源文件) - 如果你在传递一个空这个它将只使用CultureInfo.CurrentCulture

最后,你只能有每一个属性DefaultMessageInterpolator,所以您需要为每个验证属性的新DefaultMessageInterpolator。你可以利用DefaultMessageInterpolatorAggregator来处理这个问题,或者只是推出自己。

我希望这可以帮助别人。

其他提示

感谢您的帮助所有的 - 如果我能我倒是给予好评。我只是想补充一点,除了对发臭说明DefaultMessageInterpolator第一初始化电话,我也不得不做出第二个不同的初始化调用完全初始化它(我得到只使用在第一次调用一些空引用除外)。我的代码如下所示:

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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top