将 Sitecore.Data.Items.Item 序列化为 JSON

发布于 2024-10-29 22:05:59 字数 684 浏览 6 评论 0原文

我目前正在尝试构建一项服务来检索 Sitecore 数据项并将其序列化为 JSON,以便我们的 Javascript 代码可以访问 Sitecore 内容数据。

我尝试直接使用 JavascriptSerializer 和 JSON.Net 序列化对象;两者都由于递归而中断,这可能是由于子属性上的各种循环引用造成的。

我还尝试将项目序列化为 XML(通过 item.GetOuterXml()),然后将 Xml 转换为 JSON。转换效果很好;但它只检索在项目本身上设置的字段,而不是在 _standardvalues 中设置的字段。我尝试在序列化之前调用 item.Fields.ReadAll() ,以及调用 item.Fields.EnsureField(Field.id); 的 foreach 循环。然而,两者都没有检索到丢失的字段。但是,调试代码; Fields 数组似乎包含从其基本模板继承的所有字段以及在项目上设置的字段;所以我猜测 GetOuterXml 只是忽略未在该项目上专门设置的所有字段。

我越看这个,就越觉得我需要一个自定义模型类来封装数据项和必要的字段,用适当的 JSON.Net 序列化属性装饰它,然后从那里进行序列化。但这感觉像是一个肮脏的黑客行为。

所以在我走这条路之前;我想知道这里是否有人有将 Sitecore 内容项序列化为 JSON 以供客户端使用的经验,以及是否有我缺少的更简单的方法。非常感谢任何建设性的意见。

干杯, 坦率

I'm currently attempting to build a service to retrieve and serialize a Sitecore data item to JSON, so our Javascript code can access Sitecore content data.

I've tried serializing the object directly with JavascriptSerializer and JSON.Net; both broke due to recursion likely due to the various circular references on the child properties.

I've also attempted to serialize the item to XML (via item.GetOuterXml()), then converting the Xml to JSON. The conversion worked fine; but it only retrieves fields that were set on the item itself, not the fields that were set in the _standardvalues. I tried calling item.Fields.ReadAll() before serializing, as well as a foreach loop with calls to item.Fields.EnsureField(Field.id); however, neither resulted in retrieving the missing fields. However, debugging the code; the Fields array appears to contain all inherited fields from its base template as well as the ones set on the item; so I'm guessing GetOuterXml is just ignoring all fields that weren't set specifically on the item.

The more I look at this, the more it looks like I'm going to need a custom model class to encapsulate the data item and the necessary fields, decorate it with the appropriate JSON.Net serialization attributes, and serialize from there. This feels like a dirty hack though.

So before I go down this road; I wanted to know if anyone here had experience serializing Sitecore content items to JSON for client-side consumption, and is there an easier way that I'm missing. Any constructive input is greatly appreciated.

Cheers,
Frank

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

隔纱相望 2024-11-05 22:05:59

我建议采用创建自定义模型类的方法来封装您需要传递给客户端的项目数据。然后将该类序列化为 JSON。这会减少您通过线路发送的数据量,并允许您选择发送哪些数据(出于安全原因)。

CustomItem 模式和分部类非常适合这种方法。在下面的代码示例中,.base 类是您的基本自定义项包装器。您可以使用此类以强类型方式访问字段和字段值。 .instance 类可用于 JSON 序列化。

通过拆分要序列化的属性,您可以对发送回请求客户端的数据进行精细控制,并且不必太担心循环引用。如果您需要对字段定义进行任何更改,您只需更改 .base 类即可,这对 JSON 序列化的影响最小。

希望这有帮助!

MyCustomItem.base.cs

public partial class MyCustomItem : Sitecore.Data.Items.CustomItem
{
    public const string TitleFieldName = "Title";

    public MyCustomItem(Item innerItem) : base(innerItem)
    {
    }

    public static implicit operator MyCustomItem(Item innerItem)
    {
        return innerItem != null ? new MyCustomItem(innerItem) : null;
    }

    public static implicit operator Item(MyCustomItem customItem)
    {
        return customItem != null ? customItem.InnerItem : null;
    }

    public string Title
    {
        get { return InnerItem[TitleFieldName]); }
    }
}

MyCustomItem.instance.cs

[JsonObject(MemberSerialization.OptIn)]
public partial class MyCustomItem
{
    [JsonProperty("Title")]
    public string JsonTitle
    {
        get { return Title; }
    }
}

I would suggest pursuing your approach of creating a custom model class to encapsulate just the item data you need to pass to the client. Then serialize that class to JSON. This cuts down on the amount of data you're sending over the wire and allows you to be selective about which data are being sent (for security reasons).

The CustomItem pattern and partial classes lend themselves to this approach very well. In the code samples below, the .base class is your base custom item wrapper. You can use this class to access fields and field values in a strongly-typed manner. The .instance class could be used for JSON serialization.

By splitting out the properties you want serialized, you have granular control over the data being sent back to the requesting client and you don't have to worry as much about circular references. If you need to make any changes to field definitions, you could simply change your .base class with minimal impact on your JSON serialization.

Hope this helps!

MyCustomItem.base.cs

public partial class MyCustomItem : Sitecore.Data.Items.CustomItem
{
    public const string TitleFieldName = "Title";

    public MyCustomItem(Item innerItem) : base(innerItem)
    {
    }

    public static implicit operator MyCustomItem(Item innerItem)
    {
        return innerItem != null ? new MyCustomItem(innerItem) : null;
    }

    public static implicit operator Item(MyCustomItem customItem)
    {
        return customItem != null ? customItem.InnerItem : null;
    }

    public string Title
    {
        get { return InnerItem[TitleFieldName]); }
    }
}

MyCustomItem.instance.cs

[JsonObject(MemberSerialization.OptIn)]
public partial class MyCustomItem
{
    [JsonProperty("Title")]
    public string JsonTitle
    {
        get { return Title; }
    }
}
岁月无声 2024-11-05 22:05:59

我想知道使用 XSLT 递归构建 JSON 是否会更好?

I wonder if you wouldn't be better off using an XSLT to recursively build the JSON?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文