2

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 から取得する方法はありますか?

4

2 に答える 2

2

わかりました、これは古い質問であることは知っていますが、同じことをしようとしたときにこれに出くわしました。それは私が始めるのに役立ちました.

問題のコードは正しい軌道に乗っていたと思いますが、いくつか問題があります。ResourceManagerインターポレーターは、および詳細で完全に初期化されていませんでした。また、検証属性ごとCultureに 1 つしか持てないという事実を許容していないようです。DefaultMessageInterpolatorまた、補間されたメッセージを取得するために検証しているオブジェクトのインスタンスは必要ありません。

属性値でインターポレーターを初期化する問題のコードでは、使用する詳細でインターポレーターを初期化する必要もありますResourceManager

これは、次のシグネチャを持つオーバーロードInitializeされたメソッドを使用して実行できます。DefaultMessageInterpolator

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

最初のパラメーターは、エラー メッセージに独自のリソース ファイルを使用する場合のユーザー定義の ResourceManager です。既定の ResouceManager を使用するだけの場合は、null を渡すことができます。2 番目のパラメーターは、既定の ResourceManager です。渡すことができます。

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

このため、最後のパラメーターは使用するカルチャです (NHibernate.Validator には、いくつかの言語の検証メッセージを含むリソース ファイルが付属しています) - これに null を渡すと、単に使用されますCultureInfo.CurrentCulture

最後に、属性ごとに 1 つしか持てないため、検証属性ごとDefaultMessageInterpolatorに新しい属性を作成する必要があります。DefaultMessageInterpolatorを使用してDefaultMessageInterpolatorAggregatorこれを処理することも、自分でロールすることもできます。

これが誰かに役立つことを願っています。

于 2011-03-10T00:16:12.740 に答える
1

ご協力いただきありがとうございます。できれば賛成します。Stank が説明する DefaultMessageInterpolator の最初の Initialize 呼び出しに加えて、それを完全に初期化するために 2 番目の異なる Initialize 呼び出しを行う必要があったことを追加したかっただけです (最初の呼び出しのみを使用して、いくつかの 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);
}
于 2012-02-20T21:20:47.697 に答える