私の MVC4 アプリでは、ログインしているかどうか (私の場合は FormsAuthentication) に応じて異なる動作をする必要があるアクションがいくつかあります。
たとえば、「RenderAccountAndProfile」メソッドを持つ AccountController があります。ログアウトすると、対応する部分ビューにログイン プロンプトとボタンが表示されます。ユーザーがログインしている場合、ユーザーのプロファイル リンクがログアウト ボタンの横に表示されます。
私がこれまでプロジェクトで採用してきたアプローチは、単純に if ステートメントを線に沿って配置することです...
if (HttpContext.User.Identity.IsAuthenticated)
{
...
}
else
{
...
}
ただし、このアプローチのかなりエレガントな代替手段と思われるものを作成しました。
非常に単純な AnonymousUsersOnly という新しい属性を作成しました。
public class AnonymousUsersOnlyAttribute : System.Web.Mvc.ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(System.Web.Mvc.ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
return !controllerContext.HttpContext.User.Identity.IsAuthenticated;
}
}
私の AccountController クラスは Authorize 属性で装飾されています。これにより、次のコードを使用できるようになりました。
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
[AnonymousUsersOnly]
[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Anonymous()
{
// create a "logged out" view model
return Content("**NOT LOGGED IN** - LOG IN HERE");
}
[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Authorized()
{
// create a "logged in" view model
return Content("**LOGGED IN** - LOG OUT");
}
}
私のアクション メソッドは単一責任の原則に準拠しているため、このアプローチは非常に気に入っています。各メソッドは、ログイン状況またはログアウト状況のいずれかのみを処理するようになりました。トラフィックを誘導する「if」ステートメントはもう必要ありません。
これにより、各メソッドが 2 つではなく 1 つの結果のみに関係するようになったため、単体テストも容易になるはずです。単体テストを記述して、各結果を個別にテストし、異なるメソッドを呼び出すことができます。
明らかに、同じ署名を持つ 2 つのメソッドを持つことはできないため、ActionName 属性を使用する必要があります。
ここであなたの批評をいただければ幸いです。これはエレガントなソリューションだと思いますか? このアプローチの長所と短所は何ですか? また、これにはどのようなセキュリティへの影響/リスクがありますか?