0

私のプロジェクトにはこの構造があります。
EmployeeControllerレイヤーは、EmployeeBusinessLogic(bll)レイヤーを呼び出すEmployeeApiレイヤーを呼び出します。

コントローラはEmployeeModelで動作し、bllはEmployeeEntity(nhibernate)で動作します。
APIレイヤーは、モデルをモデルからエンティティに変換し、bllに渡します。
検証はコントローラー(MVC)で機能し、すでに検証されたBLLに到達します。
bllでエンティティを再度検証する必要がありますか?誰かが私のbllを開発して再利用すると、検証されていないデータが送信される可能性があるためです。データを2回検証する必要がありますか?BLLとコントローラーで?
モデルはエンティティに80%似ているので、私にとっては重複のように見えます。
ここでの回避策は何ですか?ありがとう

4

2 に答える 2

3

BLLはシステムのコアであるため、常に検証します。システムは、制御不能になる可能性のあるサービスや、さまざまなニーズを持つアプリケーションによって使用される可能性のあるサービスを通じて公開されるため、データがどこから来たとしても、データが有効であることを確認する方法です。

たとえば、次の例について考えてみます。

MVCアプリケーション| 内部cmdツール| サードパーティアプリケーション

サービスレイヤー

ビジネスレイヤー

まず、コアビジネスレイヤーとサービスレイヤーの上にMVCアプリケーションを作成します。次に、アプリケーションコア上でいくつかの操作を実行できる内部コマンドラインツールを作成することをお勧めします。ビジネスレイヤーで検証していなかった場合は、MVCアプリケーションによって実行された検証を繰り返す必要があります。あなたはそれと一緒に暮らすことができますが、あなたがあなたのサービスをサードパーティに公開するならば、あなたのサービス層の消費者はあなたのコントロールの外にさえあるかもしれません。したがって、最終的にデータを完全に信頼する唯一の方法は、データを永続化する前にビジネスレイヤーで検証することです。

また、アプリケーションによっては、ASPMVCアプリケーションのコントローラーやクライアントの検証などの他のレイヤーに検証を追加することも役立ちます。そうすれば、操作はできるだけ早く失敗し、ユーザーにはできるだけ早くエラーが通知されます。

たとえば、MVCアプリケーションでは、jquery検証とMVC控えめな検証を使用して、クライアント側で単純な検証が機能するため、エラーが見つかった場合でも、サーバーにデータを返送して応答を待つ必要はありません。また、コントローラーアクションには、ビューモデルが検証される別の検証ステップがあります。コントローラでエラーが見つかった場合、それはModelStateに追加され、ユーザーは通常、エラーが表示されてアクションを実行できる画面にリダイレクトされます。最後に、アプリケーションコアは、入ってくるデータを検証し、見つかったエラーはすべてスタックに送り返されます。

あなたが言ったように、あなたはたくさんの検証コードを繰り返すようですが、この影響を最小限に抑える方法があります。ASP MVCを使用している場合、例として、データ注釈と検証ライブラリを混在させることができます。

  • モデルやビジネスオブジェクトにデータアノテーションを使用して、requiredsや正規表現などの最も単純な検証を行うことができます。独自のデータ注釈検証属性を開発することもできます。

    public class EmployeeModel
    {
        [Required]
        public string Name {get; set;}
        ...
    }
    
    public class EmployeeEntity: BaseEntity
    {
        [Required]
        public string Name {get; set;}
        ...
    }
    
  • ビジネスレイヤーでは、データアノテーション属性のみを考慮したベースバリデーターを作成します。(ここで説明されているアプローチに似たもの:http: //odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx

    public class BaseValidator<T> where T: BaseEntity
    {
        public virtual ValidationResult Validate(T entity)
        {
             ... validate data annotations here ...
        }
    }
    
  • これにより、クライアント側、コントローラー、およびビジネスレイヤーで、主にユーザー入力に関連する同じ基本ルールのセットが提供されます。

  • より複雑な検証ロジックを備えたエンティティの場合、データアノテーション属性のみを考慮したものからビジネスレイヤー上の特定のバリデーターを派生させます。そのエンティティタイプに固有のより複雑な検証ロジックを追加します。

    public class EmployeeValidator: BaseValidator<EmployeeEntity>
    {
        public override ValidationResult Validate(EmployeeEntity entity)
        {
             base.Validate(entity);
    
             ... perform complex BLL calculations ...
        }
    }
    
  • 最後に、ビジネスレイヤーから発生した検証エラーをModelStateに追加するコードをコントローラーレイヤーに追加します。たとえば、基本コントローラークラスに次のようなメソッドを追加できます。

    public void AddValidationsToModelState(ValidationResult validationResult)
    {
        foreach(var error in validationResult.Errors)
        {
            ModelState.AddModelError(error.property, error.message);
        }
    }
    

最終的には、データ注釈属性の共通の共有ライブラリと、ビジネスレイヤーの特定の検証手順の一部になります。それが役に立てば幸い!

于 2012-11-24T18:10:39.977 に答える
0

個人的には、サービスの境界を越えるデータを信頼することは決してありません。ビジネスロジック層が共有されるように設計されている場合は、再度検証する必要があります。はい、それは重複ですが、私はここで実際に代替案を見ていません。

于 2012-11-24T17:55:30.877 に答える