web-dev-qa-db-ja.com

ASP.NET MVCの基本コントローラークラスの適切な候補は何ですか?

ASP.NETMVCプロジェクトでベースコントローラーを使用することについて多くの人が話しているのを見てきました。私が見た典型的な例は、ロギングまたはおそらくCRUDスキャフォールディングのためにこれを行います。基本コントローラークラスの他の良い使用法は何ですか?

27
kenwarner

基本コントローラークラスの適切な使用法はありません。

今私を聞いてください。

Asp.Net MVC、特にMVC 3には、すべてのコントローラーに機能を追加するためのより分離された方法を提供する多数の拡張性フックがあります。コントローラクラスは非常に重要であり、アプリケーションの中心であるため、それらを軽量で機敏に保ち、他のすべてのものと疎結合にすることが非常に重要です。

  • ロギングインフラストラクチャはコンストラクタに属し、DIフレームワークを介して注入する必要があります。

  • CRUDスキャフォールディングは、コード生成またはカスタムModelMetadataプロバイダーによって処理される必要があります。

  • グローバル例外処理は、カスタムActionInvokerで処理する必要があります。

  • グローバルビューのデータと承認は、アクションフィルターで処理する必要があります。 MVC3のグローバルアクションフィルターでさらに簡単に。

  • 定数は、ApplicationConstantsなどと呼ばれる別のクラス/ファイルに入れることができます。

ベースコントローラーは通常、MVCのさまざまな拡張性部分をすべて知らない経験の浅いMVC開発者によって使用されます。今私を誤解しないでください、私はすべての間違った理由でそれらを使用する人々を判断して協力していません。一般的な問題を解決するためのより多くのツールを提供するその単なる経験。

基本コントローラークラス以外の拡張性フックで解決できない問題は1つもないと私はほぼ確信しています。生産性に重大な理由があり、Liskovに違反しない限り、最も緊密な形式の結合(継承)を採用しないでください。アプリケーションにはるかに大きな影響を与える密結合を導入するよりも、public ILogger Logger { get; set; }のようにコントローラー全体でプロパティを20回入力するのに1秒未満かかる方がはるかに望ましいです。

UserIdやマルチテナントキーのようなものでも、ベースコントローラーの代わりにControllerFactoryに入れることができます。基本コントローラークラスの結合コストは、それだけの価値はありません。

39
John Farrell

承認にはベースコントローラーを使用するのが好きです。

各アクションを「Authorize」属性で装飾する代わりに、ベースコントローラーで承認を行います。ログインしたユーザーの承認済みアクションリストがデータベースから取得されます。

承認の詳細については、以下のリンクをお読みください。 カスタムコントローラーファクトリで共通の承認を行うためのグッドプラクティス?

8
vrluckyin

セッションやアプリケーションデータなどにアクセスするために使用します。

アプリ名などを保持するアプリケーションオブジェクトもあり、基本クラスからアクセスします

本質的に私は私が頻繁に繰り返すことのためにそれを使用します

ああ、私はそれをビジネスロジックやデータベースアクセスに使用しないことを言及する必要があります。定数は、基本クラスにとってもかなり良い賭けだと思います。

3
griegs

私は自分のプロジェクトの多くでベースコントローラーを使用していて、素晴らしい仕事をしました。私は主に

  • 例外ログ
  • 通知(成功、エラー、追加..)
  • HTTP404エラー処理の呼び出し
3
AkxumiteEmpire

私の経験から、ベースコントローラーに配置したいロジックのほとんどは、理想的にはアクションフィルターに入ります。アクションフィルターは定数でのみ初期化できるため、場合によってはそれができないことがあります。場合によっては、システム内のすべてのアクションメソッドに適用するアクションが必要です。その場合、新しいactionFilter属性ですべてのアクションメソッドに注釈を付けるよりも、ロジックをベースに配置する方が理にかなっている場合があります。

また、サービスを参照するプロパティ(コントローラーから切り離されている)をベースに配置すると、アクセスが簡単になり、一貫して初期化できるので便利です。

2
hannasm

i18N ライブラリを使用した国際化のために現在ベースコントローラを使用しています。これは、コントローラー内の任意の文字列をローカライズするために使用できるメソッドを提供します。

1
Random

私がしたことは、汎用コントローラーの基本クラスを使用して以下を処理することでした。

  • 基本クラスが処理するようにコンストラクターパラメーターとしてBaseCRUDController<Key,Model>オブジェクトを必要とするICRUDService<TModel>を作成しました作成/編集/削除 =。そして、カスタムの状況で処理するために仮想モードで確実に
  • ICRUDService<TModel>には保存/更新/削除/検索/ResetChache/...作成したリポジトリごとに実装して、機能を追加できるようにします。
  • この構造を使用して、PagedList/AutoComplete/ResetCache/IncOrder&DecOrder(モデルがIOrderable)
  • エラー/通知メッセージ処理:@TempData["MHError"]コードを含むレイアウトの一部と次のようなベースコントローラーのプロパティ

    public Notification Error {set {TempData ["MHError"] = value; } get {return(Notification)TempData.Peek( "MHError"); }}

この抽象クラスを使用すると、毎回記述したり、コードジェネレーターで作成したりする必要のあるメソッドを簡単に処理できました。しかし、このアプローチには弱点もあります。

1
ghazyy

BaseControllerは次の2つの目的で使用します。

  1. すべてのコントローラーに適用する必要がある属性。
  2. リダイレクトURLがローカルURLであることを確認することにより、オープンリダイレクト攻撃から保護するリダイレクトのオーバーライド。これにより、リダイレクトを呼び出すすべてのコントローラーが保護されます。
1
Henry Fieger

フィルタはスレッドセーフではありません。データベースへのアクセスと依存性注入の条件により、データベース接続は他のスレッドによって閉じられる可能性があります。

0
B.W