Edited at

複数ボタンのあるFormで押されたボタンを判断する

More than 1 year has passed since last update.


判断方法


  • ボタンにname属性を利用して、モデルバインディングで取得する。

  • JavaScriptでResponsデータを操作する。

  • セレクター属性を作成し、必要なアクションにそのセレクター属性を設定する。

2番目のJavaScriptによる方法については、個人的には利用しないので説明しません。


ボタンにname属性を利用する(nameがボタン毎に異なる場合)


ビューのコード

@using(Html.BeginForm())

{
@Html.AntiForgeryToken();

// テキストボックス等の入力項目の設定

<input type="submit" name="Search" value="検索">
<input type="submit" name="Clear" value="クリア">
}



コントローラーのコード

[HttpPost]

[ValidateAntiForgeryToken]
public ActionResult Index(string search, string clear)
{
if (search != null)
{
// 検索ボタンが押された場合の処理
}

if (clear != null)
{
// クリアボタンが押された場合の処理
}
}



  • ActionResult Indexのパラメーター(search、clear)には、ボタンのvalue属性の値を受け取れます。
    (searchボタンを押した場合は、パラメーターsearchに”検索”が入り、clearはブランクです。
     clearボタンを押した場合は、パラメーターclearに”クリア”が入り、searchはブランクです。)

  • ・name属性とパラメーターで大文字、小文字の違いがあっても正常にモデルバインディングされます。


ボタンにname属性を利用する(nameが全てのボタンで同じ場合)


ビューのコード

@using(Html.BeginForm())

{
@Html.AntiForgeryToken();

// テキストボックス等の入力項目の設定

<input type="submit" name="cmd" value="検索">
<input type="submit" name="cmd" value="クリア">
}



コントローラーのコード

[HttpPost]

[ValidateAntiForgeryToken]
public ActionResult Index(string cmd)
{
if (cmd == "検索")
{
// 検索ボタンが押された場合の処理
}

if (cmd == "クリア")
{
// クリアボタンが押された場合の処理
}


この方法ではValue属性が同一のボタンが複数ある場合は正しく認識できません。

(検索ボタンが2個ある場合など)


セレクター属性を作成する

この例では、ExtensionsフォルダにButtonAttributeクラスファイルを作成します。

(実際はどのフォルダでも問題ありません)


セレクター属性のコード

using System.Reflection;

using System.Web.Mvc;

namespace Project.Extensions
{
public class ButtonAttribute : ActionMethodSelectorAttribute
{
// アクションメソッド付加時に設定したボタン名を保存
public string ButtonName { get; set; }

public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
// 設定したボタン名と同名のデータが存在するかチェック(Requestで返ってきているか)
return controllerContext.Controller.ValueProvider.GetValue(ButtonName) != null;
}
}
}



ビューのコード

@using(Html.BeginForm())

{
@Html.AntiForgeryToken();

// テキストボックス等の入力項目の設定

<input type="submit" name="Search" value="検索">
<input type="submit" name="Clear" value="クリア">
}



コントローラーのコード

using Project.Extensions;

[HttpPost]
[Button(ButtonName = "Search")]
[ValidateAntiForgeryToken]
public ActionResult Index()
{
// 検索ボタンが押された場合の処理
}



  • アクションメソッドに[Button(ButtonName = "XXXXX")]を付加する。

  • ”XXXXX"には、このアクションメソッドを実行させたいボタンのname属性値を設定する。

  • ボタンのname属性値と[Button(ButtonName = "XXXXX")]で大文字、小文字の違いがあっても
    正常に機能します。


どれを使えばいいのか

セレクター属性を作成して押されたボタンを判断するのがMVC的な方法なのかと思います。