Как получить интерполированное сообщение в NHibernate.Validator - PullRequest
2 голосов
/ 19 апреля 2010

Я пытаюсь интегрировать 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?

Ответы [ 2 ]

2 голосов
/ 10 марта 2011

Хорошо, я знаю, что это старый вопрос, но я наткнулся на это, пытаясь сделать то же самое, и это помогло мне начать - поэтому я подумал, что дам ответ.

Я думаю, что код в вопросе был на правильном пути, но есть несколько проблем. Интерполятор не был полностью инициализирован с деталями ResourceManager и Culture, и, похоже, он не учитывает тот факт, что вы можете иметь только один DefaultMessageInterpolator для каждого атрибута проверки. Кроме того, вам не нужен экземпляр объекта, который вы проверяете, чтобы получить интерполированное сообщение.

В рассматриваемом коде, где вы инициализируете интерполятор значением атрибута, вам также нужно инициализировать интерполятор с деталями ResourceManager, которые будут использоваться.

Это можно сделать, используя перегруженный метод Initialize для DefaultMessageInterpolator со следующей подписью:

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

Первый параметр - это определяемый пользователем ResourceManager. Если вы хотите использовать свой собственный файл ресурсов для сообщений об ошибках, вы можете передать значение NULL, если вы просто хотите использовать ResouceManager по умолчанию, второй параметр - ResourceManager по умолчанию. может пройти

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

для этого последний параметр - это используемая культура (NHibernate.Validator поставляется с файлами ресурсов с сообщениями проверки на нескольких языках) - если вы передадите ему ноль, он просто будет использовать CultureInfo.CurrentCulture

Наконец, вы можете иметь только один DefaultMessageInterpolator для каждого атрибута, поэтому вам нужно будет создать новый DefaultMessageInterpolator для каждого атрибута проверки. Вы можете использовать DefaultMessageInterpolatorAggregator, чтобы справиться с этим, или просто бросить свой собственный.

Надеюсь, это кому-нибудь поможет.

1 голос
/ 21 февраля 2012

Спасибо за вашу помощь всем - я бы поддержал, если бы мог. Я просто хотел добавить, что в дополнение к первому вызову Initialize для DefaultMessageInterpolator, который иллюстрирует Stank, мне также пришлось сделать второй другой вызов Initialize, чтобы полностью инициализировать его (я получал некоторые исключения Null Reference, используя только первый вызов). Мой код выглядит следующим образом:

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