JSON Objects Serialized to Empty Brackets in JsonResult

.netasp.netasp.net-mvc-5c++json.net

I am operating in the .NET Framework using ASP.NET MVC 5. I have an MVC Controller that is using Newtonsoft.Json (or json.net) to build a nice JSON object. The trouble I'm running into is that when I return my json using the JsonResult method Json(JSONdotnetObject), I end up with a result that has the same structure as what I would expect but everything is empty JArrays like so:

Expected:

{
    "prop": {
        ... some stuff ...
     },
     "another prop": {
         ... more stuff ...
     }
}

Actual:

[
    [
        ... empty ...
    ],
    [
        ... also empty ...
    ]
]

And here's the code:

public ActionResult methodName(string input) {
    JObject myJSON = new JObject();

    // Populate myJSON with children
    foreach (Thing thing in ExistingEntityFrameworkCustomClass) {
        JObject newChild = new JObject();

        // Add some props to newChild using newChild["propName"] = thing.Property

        myJSON.Add(newChild.UniqueIdTakenFromEntity.ToString(), newChild);
    }

    // The JsonResult successfully populates it's Data field with myJSON before returning.
    return Json(myJSON, JsonRequestBehavoir.AllowGet); 
}

That's not the exact structure but hopefully it illustrates what I'm experiencing. I've gone through the program line by line in VS and the JsonResult object correctly holds the JObject in the JsonResult.Data field, but when it returns something goes wrong with the serialization that ASP.NET carries out that is causing me to lose my beautiful JSON object :*(

I have worked around this issue by simply returning a JObject instead of an ActionResult from the method but this isn't ideal because I then have to manually set the response headers using Result.ContentType which feels like a hack.

Let me know if you have any ideas or could use more detail. Thank you for your time.

Best Answer

The problem is that the Json method in the MVC Controller class uses JavaScriptSerializer internally (not Json.Net), and does not know how to serialize a JObject properly. Try using the Content method instead:

public ActionResult methodName(string input) {
    JObject myJSON = new JObject();

    // Populate myJSON with children

    return Content(myJSON.ToString(), "application/json", Encoding.UTF8); 
}

Alternatively, you can implement your own JsonNetResult class as shown in James Newton-King's blog article, ASP.NET MVC and Json.NET.

Related Question