1

編集
済み私が取り組んでいるプロジェクトでは、Business、DataAccess、および DataTransferObjects の 3 つのレイヤーが存在します。ビジネス層では、検証メカニズムを構築する必要があり、使用したいと考えていますDataAnnotation

Asp.net MVC 標準アプリケーションでは、Controllerクラスが検証を担当し、プロパティによって検証にアクセスして編集できModelStateます。

クラスDataAnnotationを使用せずにマークされた DataTransferObject を検証する必要があります。Controller代わりに、ビジネス層でカスタム クラスを使用する必要があります。

これまでのところ、検証に焦点を当てたすべての DataAnnotations が から継承されていることを理解しましたValidationAttribute。クラスを動的に検証し、エラー メッセージを .xml に入れるにはどうすればよいDictionary<string,string>ですか? (Controller.ModelStateモデルを検証し、エラー メッセージの辞書を作成するように)。

4

2 に答える 2

1

アプリケーションの説明によると、それはかなり標準的なもののようであり、意図した方法で DataAnnotations を使用しても問題はありません。ここでは、アプリケーションがどのように構造化されているか (不足している詳細を埋めるため) についていくつかの仮定を立て、ビジネスの検証に DataAnnotations をどのように使用できるかを説明します。

ビジネス層は、アプリケーション ドメインを反映するオブジェクト モデルで構成されていると想定しています。ドメイン モデル内の各オブジェクトは、ビジネス ルールを実装する属性と潜在的なメソッドを公開します。これは、検証をコーディングするアプリケーション層であり、実際、ドメイン検証ルールに適した場所です。

データ アクセス レイヤーに Entity Framework または同様の ORM を使用していると仮定しています。

MVC コントローラーは、ドメイン モデルに直接アクセスしません。代わりに、ViewModel (データ転送オブジェクトと呼びます) を使用して、個々のビューのデータを適切に構造化します。したがって、ViewModel には、ドメイン検証規則が適用されるドメイン モデルから抽象化されたデータが含まれます。

さて、これはすべて問題なく、意図したとおりです。特定のビューのドメイン検証規則をオーバーライドする場合は、ViewModel のプロパティに他の DataAnnotations を追加できますが、必須ではありません。ただし、クライアント側の検証はビュー モデル プロパティに対して MVC によって実行されますが、基になるドメイン オブジェクトに対しては実行されません。

したがって、ModelState.IsValidこの場合、メソッドを使用しても機能しません。ドメイン モデルで検証を実行するにはDbEntityValidationException、オブジェクトを保存しようとした後にトラップできます。

[HttpPost]
public ActionResult Edit(int id, BlogView view)
{
    try
    {
        Blog blog = Mapper.Map(view);      //map view model to domain object using eg. Automapper
        db.Entry(blog).State = EntityState.Modified;
        db.SaveChanges();
       return RedirectToAction("Index");
    }
    catch(DbEntityValidationException ex)
    {
        var error = ex.EntityValidationErrors.First().ValidationErrors.First();
        this.ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
        return View();
    }
}

EntityFramework によってスローされた例外に依存したくない場合は、DbContext.GetValidationErrors()メソッドを使用して明示的に検証をトリガーできます。

foreach (var validationResults in db.GetValidationErrors())
{
    foreach (var error in validationResults.ValidationErrors)
    {
        Debug.WriteLine("Entity Property: {0}, Error {1}",
                          error.PropertyName,error.ErrorMessage);
    }
}

または、ドメイン オブジェクトでIValidatableObjectインターフェースを実装し、その Validate() メソッドを使用することもできます。

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (Title == BloggerName)
    {
        yield return new ValidationResult
         ("Blog Title cannot match Blogger Name", new[] { "Title", “BloggerName” });
    }
}

詳細については、 http://msdn.microsoft.com/en-gb/data/gg193959.aspxを参照してください。

于 2013-10-04T13:11:33.700 に答える