Как получить интерполированное сообщение в Nibernate.validator
-
27-09-2019 - |
Вопрос
Я пытаюсь интегрировать 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));
Я знаю, что вышеупомянутое представляет собой довольно сложный код для кажущегося простого вопроса, но я все еще застрял без решения. Есть ли способ получить интерполированную строку из NHVALDATOR?
Решение
Хорошо, так что я знаю, что это старый вопрос, но я наткнулся на это, пытаясь сделать то же самое, и это помогло мне начать - поэтому я думал, что предоставил ответ.
Я думаю, что код в вопросе был на правильном пути, но есть пара проблем. Интерполятор не был полностью инициализирован с ResourceManager
а также Culture
детали, и, похоже, не позволяют за то, что вы можете иметь только один 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());
Для этого последний параметр является культурой для использования, (Nibernate.validator поставляется с файлами ресурсов с сообщениями о проверке на нескольких языках) - если вы проходите к этому, он просто будет использовать CultureInfo.CurrentCulture
Наконец, вы можете иметь только один DefaultMessageInterpolator
за атрибут, так что вам нужно будет создать новый DefaultMessageInterpolator
Для каждого атрибута проверки. Вы могли бы использовать DefaultMessageInterpolatorAggregator
Чтобы справиться с этим или просто катите свой собственный.
Я надеюсь, что это поможет кому-то.
Другие советы
Спасибо за вашу помощь все - я бы упростил, если бы мог. Я просто хотел добавить, что в дополнение к первому инициализующему вызову по умолчаниюMessageInterPolator, который Stank иллюстрирует, мне также пришлось сделать второй другой инициализировать вызов, чтобы полностью инициализировать его (я получал некоторые исключения для нулевых ссылок, используя только первый вызов). Мой код выглядит следующим образом:
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);
}