4

ここで提起された最近の質問: ASP.NET MVC: Is Data Annotation Validation Enough?

...データ注釈の検証 (モデル バインダーによってトリガーされる) に依存するだけでは、検証が常に実行されることを保証するには不十分であると結論付けられました。サービス層 (または ModelBinding が発生した後の別の場所) に同じ検証ロジックを追加する必要があります。残念なことに、検証コードを複製することになります (1 回はデータ注釈で、もう 1 回はサービス層で)。データ注釈で定義されている内容に基づいて、サービス層が検証をトリガーする簡単な方法はありますか? これが可能であれば、両方の長所を活用できます...検証コードを繰り返す必要はありませんが、検証が常に実行されるようにします。

4

3 に答える 3

4

このブログの助けを借りて : http://goneale.com/2009/03/04/using-metadatatype-attribute-with-aspnet-mvc-xval-validation-framework/データ注釈によって定義された検証に基づくオブジェクト。ValidateAttribute から派生した検証属性を実行します。サービス層 (または DomainModel) からこのメソッドにオブジェクトを渡すことができるようになり、サービス層はコントローラーに依存しなくなりました。これにより、データをデータベースに永続化する前に常に検証が実行されます。グラハムが使用していた拡張メソッドの一部にアクセスできないように思われるため、ブログのコードをそのまま使用することはできませんでした。そのため、これが私のバージョンです。

    public static IList<KeyValuePair<string, string>> GetErrors(object obj)
    {
        // get the name of the buddy class for obj
        MetadataTypeAttribute metadataAttrib = obj.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).FirstOrDefault() as MetadataTypeAttribute;

        // if metadataAttrib is null, then obj doesn't have a buddy class, and in such a case, we'll work with the model class
        Type buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : obj.GetType();

        var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast<PropertyDescriptor>();
        var modelClassProperties = TypeDescriptor.GetProperties(obj.GetType()).Cast<PropertyDescriptor>();

        var errors = from buddyProp in buddyClassProperties
                           join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name // as this is an inner join, it will return only the properties that are in both the buddy and model classes
                           from attribute in buddyProp.Attributes.OfType<ValidationAttribute>() // get only the attributes of type ValidationAttribute
                           where !attribute.IsValid(modelProp.GetValue(obj))
                           select new KeyValuePair<string, string>(buddyProp.Name, attribute.FormatErrorMessage(string.Empty));

        return errors.ToList();
    }

このコードは、バディ クラスがあるクラスとないクラスの両方で機能しますが、バディ クラスを使用しない場合は、このコードを少し簡略化できます。これが役に立つことを願っています。

于 2009-10-15T04:58:33.833 に答える
0

私は同じことを達成したいと思い、ジョニーの答えを試しました。RequiredIf 属性を使用するなど、他のプロパティに関連する検証が行われるまでは正常に機能します。

System.ComponentModel.DataAnnotations で Validator クラスを使用することになりました。これは実際にはこれに対応しており、通常適用されるのとまったく同じ完全なロジックを適用する必要があります。

これは、Validator クラスでこれを行う方法を示すメソッドの例です。

    public static bool TryValidate(object obj, List<ValidationResult> results = null)
    {
        var context = new ValidationContext(obj, serviceProvider: null, items: null);
        return Validator.TryValidateObject(obj, context, results, true);
    }
于 2016-12-18T16:39:21.310 に答える
0

前の質問で私の回答を確認していませんか?
DTO の DataAnnotation 属性に基づいて自動検証を行うコードを提出しました。DTO がコントローラー アクションのパラメーターで使用されている限り、それらはこの属性によって取得され、何があっても検証されます。

唯一の問題は、DTO をどのように生成するかということです。

  1. あなたはそれらを自分で書きますか?
  2. EFなどを使用していますか?
  3. 他の手法 (T4 など) を使用して自動生成しますか?

DTO クラスの生成を制御できる場合は、それらにインターフェイスを追加することもできます。私が投稿したコードは、T4 over EF、xVal、および DataAnnotation とValidate()、各エンティティ クラスに実装されているメソッドを宣言するカスタム インターフェイスを使用しています。

于 2009-10-13T21:37:10.487 に答える