0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ASP.NET MVCで共通処理をまとめる

Posted at

はじめに

どの画面のControllerでも行うチェックがあり、複数箇所で同じ記載をしていたためまとめたいと思っていました。
現場での画面開発が初めてで、しかも新規作成だったため手探り状態でしたが、今回学んだことを備忘録にまとめます。

Filter

JavaのServletでFilterを使ったことがあるので、ASP.NETにもあるんだという感じでした。
ASP.NET Core7.0の説明ですが、詳しくは公式ドキュメントをご覧ください。
ネットで調べても使用例はあまり見つけられなかったため、公式ドキュメントを読み込んで試行錯誤しました。

今回はControllerアクションの最初で処理を行いたかったので、「アクションフィルター(IActionFilter)」を使いました。

SampleActionFilter.cs
public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // アクション実行前処理
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // アクション実行後処理
    }
}

例外処理も同じ記載があるのでまとめたいと思い、「例外フィルター(IExceptionFilter)」を使えたらいいなと思ったのですが、DbExceptionとExceprionとあるので分け方が分からず、こちらは次に紹介する親Controllerに記載しました。
はじめはFilterクラスを作成していたのですが、Controllerでも使えるようでまとめて親Controllerに記載することにしました。

親Controller

共通処理を親Controllerに書いておき、継承してそのメソッドを使うようにしました。
親ControllerをBaseControllerとします。

OnActionExecutingはアクションメソッドの前に一律で処理されます。
コントローラ名、アクション名が取得できるので特定のコントローラ、アクションを除外できます。

BaseController.cs
public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        RouteValueDictionary routeValue = filterContext.RouteData.Value;
        // ログイン画面の場合は除外
        if (routeValue["controller"].ToString() == "Login")
        {
            return;
        }
        
        // 初期処理の場合
        if (routeValue["action"].ToString() == "Index")
        {
            // 処理
        }
            
        // 共通で行いたい処理

        base.OnActionExecuting(filterContext);
    }
    
    // メソッドが続く
}

セッションチェックなどの共通チェックはメソッドにしました。

BaseController.cs
protected bool SessionCheck()
{
     // セッションの値があればtrue。なければfalse。
}

複数のチェックもまとめたりもしました。

BaseController.cs
protected bool CommonCheck()
{
    // セッションチェック
    if (!SessionCheck())
    {
        return false;
    }

    // トークンチェック
    if (!TokenCheck())
    {
        return false;
    }

    // 権限チェック
    if (!RoleCheck())
    {
        return false;
    }

    return true;
}

各コントローラで使用する場合は下記のようになります。
通常の場合とAjaxの場合でreturnの記載が違うためこのようにしました。

TopController.cs
public class TopController : BaseController
{
    public ActionResult Index()
    {
        if (!CommonCheck())
        {
            // エラー画面に遷移
            return RedirectToAction("Error", "Error");
        }  
    }
}

Exceptionは重複部分だけBaseControllerに書いて、そのメソッドを使うようにしました。

最後に

各コントローラにメソッド使用とreturnの記載が必要なため、まとめる意味があまりなさそうな気がしましたが、コードの重複がなくなりスッキリしました。メッセージIDの修正があった時もBaseControllerだけ修正すればよかったのでやった甲斐はあったと思います。
フレームワークの知識と経験がまだまだ足りないのでまだ知らないことや良い方法あるかもしれませんが、随時更新していきたいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?