web-dev-qa-db-ja.com

asp.net mvcで汎用コントローラーを作成することは可能ですか?

汎用コントローラーを作成しようとしています。

public class MyController<T> : Controller where T : SomeType
{ ... }

しかし、それを使おうとすると、どこでもこのエラーが発生します...

コントローラ名は「Controller」で終わる必要があります

だから、私の質問、asp.net mvcで汎用コントローラーを作成することは可能ですか?

ありがとう!

27
Aaron Palmer

私があなたを正しく理解している場合、あなたがやろうとしていることは、特定のモデルに対するすべての要求をタイプTの汎用コントローラーを介してルーティングすることです。

要求されたモデルに基づいてTを変更する必要があります。

_/Product/Index_がMyController<Product>.Index()をトリガーするようにします

これは、独自のIControllerFactoryを記述し、次のようにCreateControllerメソッドを実装することで実現できます。

_public IController CreateController(RequestContext requestContext, string controllerName)
{
    Type controllerType = Type.GetType("MyController")
                              .MakeGenericType(Type.GetType(controllerName));
    return Activator.CreateInstance(controllerType) as IController;
}
_
37
Jeff Fritz

はい、できます。大丈夫です。私はそれらを自分でたくさん使用しました。

確認する必要があるのは、MyControllerから継承する場合でも、タイプ名をコントローラーで終了することです。

public class FooController :  MyController<Foo>
{ 
 ...
}
9
Iain Holder

デフォルトのコントローラーファクトリは、要求をディスパッチするコントローラーを見つけようとするときに、コントローラー名の周りに「規則」を使用します。必要に応じて、このルックアップ機能をオーバーライドできます。これにより、汎用コントローラーが機能するようになります。

このMSDNの記事...

http://msdn.Microsoft.com/en-us/magazine/dd695917.aspx

...何が起こっているのかについての良い記事があります。

1
Martin Peck

これは asp.net mvc generic controller の複製であり、実際には正解が含まれています。ジェフフリッツの答えは絶対に正しくありません。独自のIControllerFactoryを作成しても、表示されているエラーを生成しているExpressionHelper.GetRouteValuesFromExpressionの制限を超えることはありません。独自のIControllerFactoryを実装すると、RedirectToAction、BuildUrlFromExpression、ActionLink、RenderAction、BeginForm、これらを呼び出すメソッドを呼び出すたびにエラーが発生します。

私にとって興味深いのは、Microsoftの「慣例による制限」は、ExpressionHelper.GetRouteValuesFromExpressionメソッドの型に設定された制約「whereTController:Controller」によってすでに適用されていることです。ジェネリックは、コンベンションの検証を満たすことはありません。

string controllerName = typeof(TController).Name;
if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
    throw new ArgumentException(MvcResources.ExpressionHelper_TargetMustEndInController, "action");
}

typeof(AnyGeneric).Nameが「Controller」で終わることはないため、「Controller」で終わるクラスに継承されない限り。

1
DaveMorganTexas

私があなただったら、 MVC source を取得し、ソースコードを使用してテストMVCプロジェクトを作成します。これにより、例外が生成される場所を調べて、一般的なアイデアと「* controller」命名規則を適用しました。

0
Matt Kocaj