7

ASP.NET MVC 3 CompareAttributeをコピーして、カスタムのCompareLessThan検証属性を作成しました。等しいかどうかを確認する代わりに、あるプロパティが別のプロパティよりも小さいことを確認します。クライアント側のエラーがある場合は、メッセージ「{0}は{1}未満である必要があります」がユーザーに表示されます。

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

[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メソッドは、CompareAttributeの場合とまったく同じです。

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

ここでは、問題が発生した場合にユーザーに表示されるエラーメッセージを生成しています。カスタムCompareLessThan属性で装飾されたプロパティのリソースファイルから表示名を取得できますが、私の質問は、比較対象の「その他」のプロパティの表示名を取得するにはどうすればよいですか?IsValidメソッドには、validationContextへの参照があり、そこから「other」プロパティのPropertyInfoオブジェクトを生成でき、表示名を取得できると思います。しかし、GetClientValidationRulesではアクセスできません。

他のプロパティの表示名にはいつでも別の値を渡すことができましたが、データアノテーションですでに指定しているので、それを導出する方法があることを期待していました。

何か案は?

4

3 に答える 3

7

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

于 2012-06-25T21:11:04.223 に答える
6

nemesvによって提供された回答はmetadata.Modelプロパティの値が0として機能しませんでした。ただし、メタデータを通じてモデルのフルネームを取得できるため、そのモデルの新しいインスタンスを作成してから作成することができます。その作成インスタンスからの新しいDataAnnonationsModelMetadataProvider。そこから、他のプロパティの表示名を取得できます。

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    Type type = Type.GetType(metadata.ContainerType.FullName);
    var model = Activator.CreateInstance(type);

    var provider = new DataAnnotationsModelMetadataProvider();
    var otherMetaData = provider.GetMetadataForProperty(() => model, type, this.OtherProperty);

    this.otherPropertyDisplayName = otherMetaData.DisplayName;

    yield return new ModelClientValidationLessThanRule(FormatErrorMessage(metadata.DisplayName), FormatPropertyForClientValidation(this.OtherProperty), this.AllowEquality);
}

より良い方法があるはずなので、私はこの解決策が本当に好きではありません(それは機能しますが)。他に何かアイデアはありますか?

于 2011-10-14T18:13:21.420 に答える
4

試したことはありませんが、プロパティを使用してモデルのプロパティを取得できmetadata.Propertiesます

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

編集:プロパティは空なので、いつでもできることです(非常にエレガントですが)。自分でメタデータを生成できます。

var provider = new DataAnnotationsModelMetadataProvider();
var otherMetaData = provider.GetMetadataForProperty(() => metaData.Model, metaData.ModelType, "OtherPropertyName");
于 2011-10-14T05:11:20.643 に答える