21

I'm trying to use the ASP.NET MVC Ajax.BeginForm helper but don't want to use the existing content insertion options when the call completes. Instead, I want to use a custom JavaScript function as the callback.

This works, but the result I want should be returned as JSON. Unfortunately, the framework just treats the data as a string. Below is the client code. The server code simply returns a JsonResult with one field, UppercaseName.

<script type='text/javascript'>
    function onTestComplete(content) {
        var result = content.get_data();
        alert(result.UppercaseName);
    }
</script>

<% using (Ajax.BeginForm("JsonTest", new AjaxOptions() {OnComplete = "onTestComplete" })) { %>
    <%= Html.TextBox("name") %><br />
    <input type="submit" />
<%} %>

Instead of showing the uppercase result, it is instead showing undefined. content.get_data() seems to hold the JSON, but only in string form. How do I go about converting this to an object?

All of this seems a bit convoluted really. Is there a better way to get at the resulting content using Ajax.BeginForm? If it's this hard, I may skip Ajax.BeginForm entirely and just use the jQuery form library.

Brian Vallelunga
  • 9,869
  • 15
  • 60
  • 87

5 Answers5

23

You can use OnFailure and OnSuccess instead of OnComplete; OnSuccess gives you the data as a proper JSON object. You can find the callback method signatures burried in ~/Scripts/jquery.unobtrusive-ajax.min.js which you should load on your page.

In your Ajax.BeginForm:

new AjaxOptions
    {
        OnFailure = "onTestFailure",
        OnSuccess = "onTestSuccess"
    }

Script block:

<script>
//<![CDATA[

    function onTestFailure(xhr, status, error) {

        console.log("Ajax form submission", "onTestFailure");
        console.log("xhr", xhr);
        console.log("status", status);
        console.log("error", error);

        // TODO: make me pretty
        alert(error);
    }

    function onTestSuccess(data, status, xhr) {

        console.log("Ajax form submission", "onTestSuccess");
        console.log("data", data);
        console.log("status", status);
        console.log("xhr", xhr);

        // Here's where you use the JSON object
        //doSomethingUseful(data);
    }

//]]>
</script>

These signatures match success and error callbacks in $.ajax(...), which might not be such a surprise after all.

This was tested using with 1.6.3 and 1.7.2.

Joel Purra
  • 24,294
  • 8
  • 60
  • 60
12

Try this:

var json_data = content.get_response().get_object();

this will give you result in JSON format and you can use json_data[0] to get the first record

VVS
  • 19,405
  • 5
  • 46
  • 65
Kobi
  • 156
  • 1
  • 5
  • OK, this worked. It still seems convoluted however. I'm not sure why they just don't return the data directly. – Brian Vallelunga Nov 20 '08 at 17:26
  • 4
    So what is get_data() supposed to do then? – Jack Ukleja Apr 17 '09 at 04:25
  • 2
    Times have changed, so for [tag:asp.net-mvc-3], see my answer using `onSuccess(data, status, xhr)`. – Joel Purra Feb 15 '12 at 07:07
  • In response to the comment by Brian, the reason they "just don't return the data directly" is because the object form is not the default form of data being returned via HTTP. When you make an http call, you get a string back. The fact is that in order to turn it into an object, you *must* take an extra step to evaluate it using the eval function. – Joel Martinez Dec 17 '08 at 01:03
  • @MaksimVi.: Not surprised at all ;) – Joel Purra Jan 14 '14 at 09:09
0

Try using the below code:

<script type='text/javascript'>
    function onTestComplete(content) {
        var result = eval( '(' + content.get_data() + ')' );
        alert(result.UppercaseName);
    }
</script>
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Russel
  • 1
0

I use:

    function onTestComplete(data, status, xhr) {
       var data2 = JSON.parse(data.responseText);
       //data2 is your object
    }
Juan Carlos Velez
  • 2,840
  • 2
  • 34
  • 48
-1

Make sure you have included MicrosoftAjax.js and MicrosoftMvcAjax.js. Then use the following calls on the returned context to get a json object out of the return.

var json = context.get_data();
var data = Sys.Serialization.JavaScriptSerializer.deserialize(json);
  • 1
    These libraries are redundant now, and highly bloated. I wouldn't want to be including them just to make one tiny call like this. A better solution would be pure jquery just using the included unobtrusive jquery scripts. – Aaron Feb 24 '11 at 06:37