Можно ли вернуть SiteMap как JsonResult?
У меня на контроллере очень простое действие, которое пытается вернуть мой XmlSiteMap в виде JsonResult:
public ActionResult Index()
{
var nodes = SiteMap.Provider.RootNode;
return new JsonResult()
{ Data = nodes, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
Однако, когда я вызываю Action, создается исключение InvalidOperationException:
"A circular reference was detected while serializing an object of
type 'System.Web.SiteMapNode'."
Есть ли способ, чтобы Json сериализовал SiteMap, или действительно любой объект, у которого есть потомки того же типа?
3 ответа
Вот как это можно сделать с помощью Json.NET ( http://json.codeplex.com/). Обратите внимание на использование ReferenceLoopHandling.Ignore
установка.
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));
}
Одна хитрость, которую вы можете использовать, когда сталкиваетесь с проблемой сериализации сложного класса в JsonResult, - это использовать LINQ и Select()
проецировать значения в перечисление по анонимному типу, содержащему только те свойства, которые вам нужны из исходного сложного класса.
Я ожидал бы, что наличие объектов того же времени, что и у детей, не должно быть проблемой, но проблема в том, что дети ссылаются на родительский объект и, следовательно, вы получаете циклическую ссылку.
Также возможно реализовать свой собственный сериализатор json для этого случая и явно обрабатывать циклическую ссылку, но это, вероятно, не лучшее решение.