6

ASP.NET MVC 3 CompareAttributeをコピーしてカスタムのCompareLessThan検証属性を作成し、等価性をチェックする代わりに、あるプロパティが他のプロパティよりも小さいかどうかをチェックします。クライアント側のエラーがある場合、メッセージ '{0}は{1}未満でなければなりません'がユーザーに表示されます。ASP.NET MVC ValidationAttribute他のプロパティの表示名を取得

私のモデルは、リソースファイルを参照する表示属性で次のように設定されています。

[CompareLessThan("AmountAvailable", ErrorMessageResourceName="CompareLessThan", ErrorMessageResourceType = typeof(Resources.ValidationMessages))] 
[Display(Name = "Amount", ResourceType = typeof(Resources.Labels))] 
public decimal Amount { get; set; } 

[Display(Name = "AmountAvailable", ResourceType = typeof(Resources.Labels))] 
public decimal AmountAvailable { get; set; } 

次にカスタム検証GetClientValidationRules方法は、ここでは、問題がある場合、ユーザーに表示されるエラーメッセージを生成している

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
{    
    yield return new ModelClientValidationLessThanRule(FormatErrorMessage(metadata.DisplayName), FormatPropertyForClientValidation(OtherProperty), this.AllowEquality); 
} 

CompareAttributeと全く同じです。私は私のカスタムCompareLessThan属性で装飾されているプロパティのリソースファイルから表示名を得ることができますが、私の質問は、私たちが比較している '他の'プロパティの表示名を取得する方法ですか? IsValidメソッドでは、 '他の'プロパティのPropertyInfoオブジェクトを生成するvalidationContextへの参照があり、表示名を取得すると思います。しかし、GetClientValidationRulesではそのアクセス権がありません。

他のプロパティの表示名に別の値を渡すこともできますが、既にデータ注釈を指定しているので、それを派生させる方法があることを期待していました。

アイデア?

答えて

5

nemesvが提供する答えはmetadata.Modelプロパティとして動作しませんでしたが、我々は新しいを作成することが可能であるので、モデルの完全な名前を持っているメタデータを介し、0の値を持っていますが、そのモデルのインスタンスを作成し、そのインスタンスから新しいDataAnnonationsModelMetadataProviderを作成します。そこから、他のプロパティの表示名を取得できます。

もっと良い方法があるはずですが、このソリューション(実際には機能していますが)は本当に好きではありません。誰にも他のアイデアはありますか?

4

は、私はそれを試していないが、あなたはmetadata.Propertiesプロパティ

metadata.Properties.Single(p => p.PropertyName == "OtherPropName").DisplayName; 

EDITとモデルのプロパティを取得することができますプロパティが空であるため、あなたはいつも何ができるか(それは非常にエレガントですが)。自分でメタデータを生成できます。

var provider = new DataAnnotationsModelMetadataProvider(); 
var otherMetaData = provider.GetMetadataForProperty(() => metaData.Model, metaData.ModelType, "OtherPropertyName"); 
+0

プロパティコレクションは常に空です。 –

+0

@NickOlsenそれは悲しいです。私はいくつかの "回避策"で私の答えを更新しました。 – nemesv

+0

それはメタデータとしても機能しません。モデルプロパティは値0だけです。あなたのロジックを使って、私はそれを行う別の方法を考え出すことができました(他の答えを見てください)。誰かが提供できるより良い方法があると私は望んでいる。 –

6

これは私が他のプロパティを取得するために管理方法であるASP.NET MVC 4のとおり:

PropertyInfo otherPropertyInfo = 
        this.Metadata.ContainerType.GetProperty(attribute.DependentProperty); 

それから私は、プロパティからDisplay attributeを得た:あなたのケースで

var displayAttribute = 
    otherPropertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true). 
    FirstOrDefault() as DisplayProperty; 

// GetName() is important to get the translated name if you're using a resource file... 
this.otherPropertyDisplayName = displayAttribute.GetName(); 

GetName()参照:

http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.name%28v=vs.95%29.aspx

+0

これは "as DisplayProperty"または "as DisplayAttribute"であることを意味しましたか?私はDisplayPropertyでは機能しませんでしたが、DisplayAttributeでは正常に動作しました。そうでなければ素晴らしい解決策。 – MVCKarl

+0

@MVCKarl:あなたが正しいと思います。答えを入力しているときに多少の混乱があったかもしれません。私はその時に私が何をしたのかを記録することはできません。 :) –

関連する問題