今日もちょいつか

お酒の飲み過ぎか、それとも歳のせいなのか毎日ちょっぴり疲れ気味なフリーのソフト屋です。ソフト開発の話題をblogにしてみます。

ASP.NET Core MVC 複数ボタンのあるFormでSubmit先を変えたい

いわゆるCRUDではなくて、
一つのフォームで新規登録・修正・削除・一覧表示をしたいと思っています。
名称を登録するだけのような簡単なマスターメンテナンス画面でも
CRUDだとその分Viewが必要になるし、操作もちょっと面倒です。

CRUDだと一つの処理に一つのSubmitですので
Controller側のアクションも簡単なのですが
一つのフォームで全ての処理を行うには複数のSubmitボタンが必要となります。

その時にController側はどのように記述すれば複数のSubmitボタンに対応できるのか
調べてみました。
いつものことですが、今回もかなりハマってしまいました。
Visual Studio Community 2017 for Mac で動作確認しています。

どうしても動かなかった方法

ネットを調べてみると、ある程度同じような方法を発見することができました。
セレクター属性を作ってクリックされたボタンごとにアクションを実行させる方法です。
ボタンのvalue属性を利用して処理を分岐する方法もありましたが
新たにセレクター属性を作ったほうがMVC的な感じがしていいと思いました。

Viewには一つのFormに更新と削除ボタンが二つあります。

<input type="submit" name="btnUpdate" value="更新" class="btn btn-primary">
<input type="submit" name="btnDelete" value="削除" class="btn btn-danger">

属性の作成はこんな感じです。

public class ButtonAttribute : ActionMethodSelectorAttribute
  {
    public string ButtonName { get; set; }

    public override bool IsValidForRequest(ControllerContext context, System.Reflection.MethodInfo methodInfo)
    {
      return context.Controller.ValueProvider.GetValue(ButtonName) != null;
    }
  }

Controller側はこんな感じ。

 [HttpPost]
 [Button(ButtonName = "btnUpdate")]
 public IActionResult Update()
 {
       ViewData["Message"] = "Update.";
       return View("test");
 }

クリックされたボタンのname属性を記述して処理を振り分けています。
すごくわかりやすくて簡単に動いてくれるはずでした。

しかし!
この方法では自分の環境では動いてくれませんでした。
英語サイトも見まくって4,5日奮闘しましたが結局動きません。

最終的に動いた方法

どうしても一つのSubmitで一つのアクションに紐付けたくて
まだ見ていなかった英語サイトを一つ一つ見ていったら思いがけない解決法を発見しました。
解決策はこれです。

<input type="submit" formaction="Update" formmethod="post" value="更新" class="btn btn-primary">
<input type="submit" formaction="Delete" formmethod="post" value="削除" class="btn btn-danger">

Viewでのhtmlの記述を変更するだけで解決することができました。
HTML5になってからボタンに「formaction」と「formmethod」が記述できるようになったのですね。
恐ろしいほどの無知さに悲しくなるのでした。
ものすごく時間をかけて悩んだ挙句こんなオチでした。
でも、解決できてよかった!

ほんのちょっとお小遣い

パソコンで仕事をしていると疲れて飽きてきちゃいます。
そんな時は、簡単にお小遣いを稼ぐのもいいですね。

短時間で高収入のコマーシャルはどれも嘘くさくて。。。
お小遣いサイトなら安全です。
(その代わり収入はちょびっとですが)
ちょびリッチはこちら
メールアドレスのみでノーリスクで利用できます。