كيفية الحصول على رسالة محرف في nhibernate.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));
أعلم أن ما سبق هو رمز معقد إلى حد ما لسؤال يبدو بسيطًا ، لكنني ما زلت عالقًا بدون حل. هل هناك أي طريقة لإخراج السلسلة المحرف من NHValidator؟
المحلول
حسنًا ، لذلك أعلم أن هذا سؤال قديم ، لكنني تعثرت في هذا الأمر عند محاولة فعل نفس الشيء ، وقد ساعدني ذلك في البدء - لذلك اعتقدت أنني سأقدم إجابة.
أعتقد أن الكود في السؤال كان على المسار الصحيح ولكن هناك بعض المشكلات. لم يتم تهيئة interpolator بالكامل مع ResourceManager
و Culture
التفاصيل ، ولا يبدو أنها تسمح بحقيقة أنه يمكنك الحصول على واحدة فقط DefaultMessageInterpolator
لكل سمة التحقق من الصحة. أيضًا ، لا تحتاج إلى مثيل للكائن الذي تقوم بالتحقق منه للحصول على رسالة محرف.
في الرمز في السؤال ، حيث تقوم بتهيئة interpolator بقيمة السمة ، تحتاج أيضًا إلى تهيئة interpolator مع تفاصيل 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);
}