Problem

I recently started using ASP.NET MVC 3 with the new Razor view engine. Everything looks great and cool at first sight. I tried to implement a simple Ajax postback form, without any success. Every time I tried to submit the form, it returned a new blank page with my data on it. A common mistake is to forget referencing the MicrosoftAjax.js and MicrosoftMvcAjax.js libraries in your master layout. After spending half an hour trying to figure out what I might have done wrong, I turned to google and MSDN.

Solution

UnobtrusiveJavaScriptEnabled was the buzzkill. By default, you’ll find this in your root web.config file:

<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

If you change the value from “true” to “false”, your Ajax will start working. I don’t know why it’s enabled by default. I’ll guess you’ll have to google it yourselves.

If you want to know more on Unobtrusive JavaScript, visit Wikipedia.

A simple Ajax form example

Some people asked me for a very basic example using Ajax and ASP.NET MVC 3. So here goes:

For starters, change the UnobtrusiveJavaScriptEnabled entry in your root web.config to “false”

<add key="UnobtrusiveJavaScriptEnabled" value="false"/>

Next, add the javascript references in your Master layout

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>

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

<body>
    @RenderBody()
</body>
</html>

Your HomeController has the default View and handles the PostBack

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public PartialViewResult Index(FormCollection data)
    {
        List<string> result = new List<string>();
        string[] input = data["MyInput"].Split(new string[] { "\n" }, StringSplitOptions.None);

        result.Add("<b><i><u>I said</u></i></b>:<br />");

        foreach (var line in input)
            result.Add(line + "<br />");

        return PartialView("_IndexPartial", result);
    }
}

You’ll have the Index view that looks like:

@{
    ViewBag.Title = "Index";
}

<h2>Hello!</h2>
<p>Please tell me something...</p>

@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "targetDiv" }))
{
    @Html.TextArea("MyInput", new { @style = "width:100%;height:200px;" });
    <br /><br />
    <input type="submit" value="What did you say?" />
}

<div id="targetDiv" style="width:100%;margin-top:20px;padding:10px;">
    ...
</div>

The _IndexPartial.cshtml will look like this:

@if (Model != null)
{
    foreach (string line in (Model as List<string>))
    {
       @Html.Raw(line)
    }
}

Eventually, it will look like this:

Ajax form

Ajax form - result

The source code is also available: Ajax Support Mvc3 Source Code