Asp.net mvc 2 如何在NHibernate.Validator中获取插入消息

Asp.net mvc 2 如何在NHibernate.Validator中获取插入消息,asp.net-mvc-2,nullreferenceexception,nhibernate-validator,Asp.net Mvc 2,Nullreferenceexception,Nhibernate Validator,我正在尝试将NHibernate.Validator与ASP.NET MVC客户端验证集成在一起,我发现的唯一问题是我无法将非插入消息转换为人类可读的消息。我原以为这是一项简单的任务,但结果却是客户端验证中最困难的部分。主要的问题是,因为它不是服务器端的,所以我实际上只需要正在使用的验证属性,而实际上我手头没有实例或其他任何东西 以下是我已经尝试过的内容的一些摘录: // Get the the default Message Interpolator from the Engine IMess

我正在尝试将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中获取插值字符串?

好的,我知道这是一个老问题,但我在尝试做同样的事情时偶然发现了这个问题,它帮助我开始了-所以我想我会提供一个答案

我认为问题中的代码在正确的轨道上,但是有几个问题。插值器没有使用
ResourceManager
Culture
详细信息完全初始化,而且它似乎不允许每个验证属性只能有一个
DefaultMessageInterpolator
。此外,您不需要验证对象的实例来获取插值消息

在问题中的代码中,如果要使用属性值初始化插值器,还需要使用
ResourceManager
的详细信息初始化插值器

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

    public void Initialize(ResourceManager messageBundle, 
                           ResourceManager defaultMessageBundle, 
                           CultureInfo culture)
第一个参数是用户定义的ResourceManager如果您想使用自己的资源文件发送错误消息,您可以传递null如果您只想使用默认的ResourceManager,第二个参数是默认的ResourceManager-您可以传递

  new ResourceManager( 
      NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
      Assembly.GetExecutingAssembly());
对于这一点,最后一个参数是要使用的区域性(NHibernate.Validator附带了带有多种语言的验证消息的资源文件)-如果将null传递给该参数,它将只使用
CultureInfo.CurrentCulture

最后,每个属性只能有一个
DefaultMessageInterpolator
,因此需要为每个验证属性创建一个新的
DefaultMessageInterpolator
。您可以使用
DefaultMessageInterpolatorAggregator
来处理此问题,也可以自己滚动

我希望这对某人有所帮助。

谢谢大家的帮助——如果可以的话,我会投赞成票。我只是想补充一点,除了Stank演示的对DefaultMessageInterpolator的第一次初始化调用之外,我还必须进行第二次不同的初始化调用来完全初始化它(我仅使用第一次调用就获得了一些Null引用异常)。我的代码如下:

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