Now, actually getting to a point: what to do when You have to have multiple buttons on a same form and, hopefully, being able to "catch appropriate events" in controller. Here's what I came up with:
Let's start with controller, in which we have two functions, both are actions available in a view "Edit". In a controller, we want to have functions like these:
public ActionResult Filter(string filterString){ ... }public ActionResult Save(FormCollection form) { ... }
First of all, they are called from a same view, so basically they should have been called the same, "Edit", but luckily, we have an attribute to assign them a real name:
[ActionName("Edit") ]
Now, we still have to tell a submit button which function to "call". It is not actually possible like that, but we can add a parameter to button, or, value:
<button name="button" value="someValue" type="submit">
Next, we somehow have to allow for a controller action to be called only for button we want, thats where this small piece of code jumps in:
public class AcceptSubmitButton : ActionMethodSelectorAttribute{public override bool IsValidForRequest(ControllerContext controllerContext,MethodInfo methodInfo){var req = controllerContext.RequestContext.HttpContext.Request;return req.Form["button"] == methodInfo.Name;}}
And our controller methods should look like:
[ActionName("Edit") , AcceptSubmitButton]public ActionResult Filter(string filterString){ ... }[ActionName("Edit") , AcceptSubmitButton]public ActionResult Save(FormCollection form) { ... }
The problem with this solution is that each time we create a submit button in a view, we have to set name attribute to "button", and value to controller method name (not action name). To take cate that this is done well, we introduce Html extension (namespace is Microsoft.Web.Mvc on purpose so it is included in every view automatically):
namespace Microsoft.Web.Mvc{public static class HtmlExtensions{public static string ActionSubmitButton(this HtmlHelper helper,string text, string actionName){return "<button name="\" value="\">+ "\" type=\"submit\">" + text+ "</button>";}}}
In view, rendering this button looks something like:
<%= Html.ActionSubmitButton("Perform filter", "Filter") %><%= Html.ActionSubmitButton("Perform save", "Save") %>
for Filter controller method, and Save method respectively.