Ajax Form and Button’s Value

I encountered a bug similar to the one posted on stackoverflow.com while working on my latest pet project. I figured out an elegant workaround and I was writing the post when I found out that it might have not been a bug after all.

The HTML of the page where the bug manifested didn’t validate. I fixed it. And the bug disappeared.

The bug occurred when we submitted a form asynchronously using Ajax.BeginForm(). When the form was submitted, the value of button clicked was not submitted along with other input fields’ values. But turned out, based on my observation, the “bug” only manifested when the HTML of the page didn’t validate.

The following is an example to show that the value of button clicked is submitted as expected when a form is submitted asynchronously.

Consider this form where a site visitor can vote for or against a subject. The subject to vote on is the statement “I love ASP.NET MVC!” and a site visitor can vote for or against the statement by clicking the + or - button respectively.

Voting Page

The code for the view (say, Vote.aspx) looks like the following.

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Vote</title>
</head>
<body>

<%using (Ajax.BeginForm("Vote", "Voting", new AjaxOptions { UpdateTargetId = "message" }))
  { %>
    <%= Html.Hidden("itemId", "1")%>
    <p>I love ASP.NET MVC!</p>

    <input type="submit" name="voteValue" value="+" />
    <input type="submit" name="voteValue" value="-" />
<%} %>

<p id="message"><%= TempData["message"] %></p>

<script type="text/javascript" src="<%= Url.Content("~/Scripts/MicrosoftAjax.js")%>"></script>
<script type="text/javascript" src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js")%>"></script>

</body>
</html>

The code for the controller (say, VotingController.cs) is the following.

using System.Web.Mvc;

namespace Examples.FormWithMultipleSubmitButtons.Controllers
{
    public class VotingController : Controller
    {
        public ViewResult Vote()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Vote(int itemId, string voteValue)
        {
            switch(voteValue)
            {
                case "+":
                    TempData["message"] = "You voted up.";
                    break;
                case "-":
                    TempData["message"] = "You voted down.";
                    break;
                default:
                    TempData["message"] = "Your vote was not recognized.";
                    break;
            }

            if(Request.IsAjaxRequest())
            {
                return Content(TempData["message"].ToString());
            }
            else
            {
                return View();
            }
        }
    }
}

When the site visitor clicks the + button, the form will be submitted asynchronously and the message “You voted up.” will appear as expected. Likewise, when the - button is clicked, the message “You voted down.” will appear.

Voting Up Message

Voting Down Message