Joe Enzminger
Joe Enzminger

Reputation: 11190

Why does POST without parameters not return JSON

I have a controller method

[HttpPost]
public ActionResult GetUserData()
{
    return Json(GetCurrentUser());
}

I'm calling it $.ajax() through a method like this:

ServerCall: function (method, args, callback) {
        $.ajax({
            type: 'POST',
            url: method,
            data: JSON.stringify(args),
            contentType: 'application/json;charset=utf8',
            dataType: 'json',
            success: function (result) {
                if (callback) {
                    callback(result);
                }
            },
            error: function (err) {
            }
        });
    }

with the call being:

ServerCall('GetUserData', null, function(data){
});

As it is, when I make this call, $.ajax returns with success, but 'data' is null. Debugging, responseText is empty. On the server side, GetUserData is called, and it is returning a properly formatted Json object (I've gone so far as to create my own JSON ActionResult and verified that data is indeed being written to the response stream.

If I add a dummy parameter to the server side method:

[HttpPost]
public ActionResult GetUserData(string temp)
{
    return Json(GetCurrentUser));
}

everything works perfectly. Browser is IE8. My question is, can anyone explain why this is happening?

UPDATE:

Note workaround solution below: I'd still be interested in knowing the root cause.

Upvotes: 4

Views: 1973

Answers (2)

Joe Enzminger
Joe Enzminger

Reputation: 11190

I was able to reproduce using Darin's code in IE8. While I don't know the root cause, I think it has something to do with how IE8 JSON.stringify handles null. Changing

data: JSON.stringify(args)

to

data: args ? JSON.stringify(args) : null

fixed the problem.

Note, the problem is intermittent - I was seeing failures in about one out of every ten calls. With the change, over 100 tests, the failure rate was zero.

Upvotes: 4

Darin Dimitrov
Darin Dimitrov

Reputation: 1038850

No repro.

Controller:

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

    [HttpPost]
    public ActionResult GetUserData()
    {
        return Json(new { foo = "bar" });
    }
}

Index.cshtml view:

<script type="text/javascript">
    var serverCall = function (method, args, callback) {
        $.ajax({
            type: 'POST',
            url: method,
            data: JSON.stringify(args),
            contentType: 'application/json;charset=utf8',
            dataType: 'json',
            success: function (result) {
                if (callback) {
                    callback(result);
                }
            },
            error: function (err) {
            }
        });
    };

    serverCall('@Url.Action("GetUserData")', null, function (data) {
        alert(data.foo);
    });
</script>

result: 'bar' is alerted (as expected).

Upvotes: 4

Related Questions