views:

76

answers:

3

I've got a very simple Action on my Controller that's attempting to return my XmlSiteMap as a JsonResult:

public ActionResult Index()
{
    var nodes = SiteMap.Provider.RootNode;
    return new JsonResult() 
        { Data = nodes, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}

However, when I call the Action, an InvalidOperationException is thrown:

"A circular reference was detected while serializing an object of 
   type 'System.Web.SiteMapNode'."

Is there a way to Json serialize a SiteMap, or indeed any object that has children of the same type?

A: 

I would expect that having objects of the same time as children should not be a problem but that the problem is that the children reference the parent object and hence you get a circular reference.

It is also possible to implement your own json serializer for this case and explicitly handle the circular reference but that is probably not the best solution.

ealgestorm
+1  A: 

Here's how you would accomplish this using Json.NET (http://json.codeplex.com). Note the use of the ReferenceLoopHandling.Ignore setting.

using Newtonsoft.Json;

public ActionResult Index() {
  JsonSerializerSettings jsSettings = new JsonSerializerSettings();
  jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

  var nodes = SiteMap.Provider.RootNode;
  return Content(JsonConvert.SerializeObject(
    new { Data = nodes }, Formatting.None, jsSettings));
}
JustinStolle
+1  A: 

One trick you can use when you hit an issue serializing a complex class to a JsonResult is to use LINQ and a Select() to project the values to an enumeration over an anonymous type containing just the properties you need from the original complex class.

Hightechrider
Good point, thanks.
Paul Suart