ASP.NET MVCおよびADO.NET Entity Frameworkのベストプラクティスエンティティ検証

.net asp.net-mvc entity-framework validation

質問

私はプロジェクトでASP.NET MVCとADO.NET Entity Frameworkを使用しています。部分クラスを介して私のエンティティに検証ロジックを追加したいです。 LINQ2SQLを使用しているNerdDinner.com ASP.NET MVCアプリケーションに示されているのと同じように動作します。主な違いは、LINQ2SQLのように "OnValidating"ではなく "OnPropertyChanging"イベントを使用する必要があるということです。

そのようにする場合、いくつか問題があります。 - "OnPropertyChanging"イベントは、デフォルトコンストラクターの呼び出しを作成するときでも常にトリガーされるため、検証ロジックを呼び出すのに最適なポイントではありません。これは本当に深刻な問題を引き起こす可能性があります(パフォーマンスの問題だけではありません)。 - MVCフレームワークと一緒に "EntityState.Detached"(私は他の方法を見つけることができませんでした)を使用してエンティティを検証する必要があるかどうかを判断するときに問題があります。エンティティはビューに表示される間にエンティティの状態を失うためです(POSTイベントでは、元のエンティティを返す代わりに新しいエンティティオブジェクトが作成されるため)。

私の質問は:ADO.NETエンティティに検証を追加するより良い方法はありますか? ADO.NETエンティティに検証を追加する実用的な方法を使用したチュートリアルは見つかりませんでした。

人気のある回答

個人的には、私はオブジェクト自体に検証を入れません。私はエンティティ検証を処理するためにxValライブラリを使用します。

xValでは、さまざまな検証規則を記述する属性を使用してエンティティクラス(または実際にはメタデータコンパニオンクラス)に注釈を付けることをお勧めします。これらの検証属性は、System.ComponentModel.DataAnnotationsで.NETに付属しているデフォルトのものです。

その後、ビジネスレイヤでオブジェクトに対して手動で検証を実行します。これは、System.ComponentModel.DataAnnotations検証ロジックを実行するメソッドを使用して行われます。私はこのように見えるものを書きました:

/// <summary>
/// Gets the validation errors for the passed in object by using reflection to retrieve the 
/// <see cref="ValidationAttribute"/>s placed on its properties or on the properties of the object's
/// metadata class (as specified by a <see cref="MetadataTypeAttribute"/> placed on the object's class)
/// </summary>
/// <param name="instance">The object to validate</param>
/// <returns>Any validation errors</returns>
/// <remarks>
/// Borrowed (and cleaned up) from
/// http://goneale.com/2009/03/04/using-metadatatype-attribute-with-aspnet-mvc-xval-validation-framework/
/// </remarks>
public static IEnumerable<ErrorInfo> Validate(object instance)
{
    //Try to get the MetadataType attribute from the object
    MetadataTypeAttribute metadataAttrib = instance.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault();

    //If the MetadataType attribute existed, get the metadata class
    //else just use the class of the object
    Type buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : instance.GetType();

    IEnumerable<PropertyDescriptor> buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast<PropertyDescriptor>();
    IEnumerable<PropertyDescriptor> modelClassProperties = TypeDescriptor.GetProperties(instance.GetType()).Cast<PropertyDescriptor>();

    //This query matches each property on the model class against the buddy class
    //gets a list of all invalid validation attributes and returns a list of
    //validation errors
    return from buddyProp in buddyClassProperties
           join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name
           from attribute in buddyProp.Attributes.OfType<ValidationAttribute>()
           where !attribute.IsValid(modelProp.GetValue(instance))
           select new ErrorInfo(buddyProp.Name, attribute.FormatErrorMessage(String.Empty), instance);
}

xValは、検証エラーをカプセル化し、それらをControllerのModelStateに簡単に追加できるようにするための、スローできる例外タイプを提供します。

xValはまた、HtmlHelperメソッドを提供することによってjQuery.Validateを利用することによってあなたのためのクライアントサイドJavaScriptフォーム検証コードを自動生成します。

それがどのように機能するかについてのチュートリアルについてはhttp://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/をチェックしてください。私はそれが全体的な雑用ではない検証を行うためのとても良い方法であることがわかりました。これは、ASP.NET MVCのやり方にぴったりです。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ