これにはいくつかのアプローチがあり、最適なアプローチは次の要素によって異なります。
- メソッドが配置されている場所
IsRegistrationNumberValid
と、ロジックを移動するかどうか。
- ユーザー入力またはドメインの整合性を検証していますか (両方をチェックする必要がありますが、それぞれの検証は別の場所で行われます)。
- 個人の好み。
私の見方では、次のオプションが利用可能です。
- コントローラーのアクション メソッドで検証します。
- インターフェイスを使用して検証し
IValidatableObject
ます。
- カスタムを使用します
ValidationAttribute
。
- サービス層で検証します。
オプション 1: コントローラーで検証します。
まず、コントローラーのアクション メソッドの値を検証し、次のModelState
ように更新するだけです。
[HttpPost]
public ActionResult Create(UserRegistrationViewData model)
{
if (ModelState.IsValid)
{
if (!someObject.IsRegistrationNumberValid(model.value))
{
ModelState.AddModelError("PropertyName", "There is an error..");
Return View()
}
else
{
// Carry out successful action here...
}
}
}
オプション 2:IValidatableObject
インターフェイスを使用します。
2 番目のよりクリーンな方法はIValidatableObject
、コントローラーからロジックを移動できるように、viewModel にインターフェイスを実装することです。
public class ViewModel : IValidatableObject
{
public int Value { get; set; }
IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
if (!staticClass.IsRegistrationNumberValid(this.Value))
{
yield return new ValidationResult("An error occured");
}
}
オプション 3: カスタム検証属性を作成します。
前述のValidationAttribute
ように、この記事に示されているようにから派生させることにより、カスタム検証属性を作成できます。
IvalidatableObject
インターフェイスとカスタム検証属性のどちらを選択するかは、通常は好みにIValidatableObject
依存しますが、検証が複数のプロパティに依存する場合 (たとえば、ある日付が別の日付の後にあるかどうかを確認する場合) は、インターフェイスが勝つケースの 1 つです。
オプション 4: サービス層で検証します。
最後に、検証がデータベースからの他の情報に依存している場合は、サービス レイヤーによる検証に関するこのチュートリアルを参照してください。この記事は完璧ではありません (サービスとコントローラーが少し密結合しすぎています) が、良いスタートであり、いくつかの変更により、非常に透過的でユーザー インターフェイスにデータベース検証エラー (主キー違反など) を渡すことができます。 -優しい方法。
おそらく、オプション 2、3、および 4 を組み合わせて使用することになります。最初のオプションを使用すると、コントローラー メソッドがより複雑になり、検証ロジックを他の場所で再利用することが難しくなるため、可能であれば最初のオプションを使用することは望ましくありません。
私のアドバイスは次のとおりです。
- ユーザー入力の整合性を検証する場合 (たとえば、日付が正しい形式であることを確認する場合) は、
IValidatableObject
インターフェイスとValidationAttribute
クラスを組み合わせて使用します。
- ドメインの整合性を検証する (重複するエンティティが入力されていないこと、またはエンティティ間の関係が定義されていることを確認する) 場合は、サービス レイヤーで検証を実行します。