Paul Suart
Paul Suart

Reputation: 6713

Is it possible to return a SiteMap as a JsonResult?

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?

Upvotes: 2

Views: 1482

Answers (3)

Ian Mercer
Ian Mercer

Reputation: 39277

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.

Upvotes: 1

JustinStolle
JustinStolle

Reputation: 4440

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));
}

Upvotes: 2

eaglestorm
eaglestorm

Reputation: 1202

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.

Upvotes: 0

Related Questions