我是EpiServer的新手,这已经让我好几天了:(
我正在寻找一种简单的方法将页面及其所有后代转换为JSON树。
我到目前为止:
public class MyPageController : PageController<MyPage>
{
public string Index(MyPage currentPage)
{
var output = new ExpandoObject();
var outputDict = output as IDictionary<string, object>;
var pageRouteHelper = ServiceLocator.Current.GetInstance<EPiServer.Web.Routing.PageRouteHelper>();
var pageReference = pageRouteHelper.PageLink;
var children = DataFactory.Instance.GetChildren(pageReference);
var toOutput = new { };
foreach (PageData page in children)
{
outputDict[page.PageName] = GetAllContentProperties(page, new Dictionary<string, object>());
}
return outputDict.ToJson();
}
public Dictionary<string, object> GetAllContentProperties(IContentData content, Dictionary<string, object> result)
{
foreach (var prop in content.Property)
{
if (prop.IsMetaData) continue;
if (prop.GetType().IsGenericType &&
prop.GetType().GetGenericTypeDefinition() == typeof(PropertyBlock<>))
{
var newStruct = new Dictionary<string, object>();
result.Add(prop.Name, newStruct);
GetAllContentProperties((IContentData)prop, newStruct);
continue;
}
if (prop.Value != null)
result.Add(prop.Name, prop.Value.ToString());
}
return result;
}
}
问题是,通过将页面结构转换为Dictionaries,我页面中的JsonProperty PropertyName注释将丢失:
[ContentType(DisplayName = "MySubPage", GroupName = "MNRB", GUID = "dfa8fae6-c35d-4d42-b170-cae3489b9096", Description = "A sub page.")]
public class MySubPage : PageData
{
[Display(Order = 1, Name = "Prop 1")]
[CultureSpecific]
[JsonProperty(PropertyName = "value-1")]
public virtual string Prop1 { get; set; }
[Display(Order = 2, Name = "Prop 2")]
[CultureSpecific]
[JsonProperty(PropertyName = "value-2")]
public virtual string Prop2 { get; set; }
}
这意味着我得到这样的JSON:
{
"MyPage": {
"MySubPage": {
"prop1": "...",
"prop2": "..."
}
}
}
而不是:
{
"MyPage": {
"MySubPage": {
"value-1": "...",
"value-2": "..."
}
}
}
我知道使用自定义ContractResolvers进行JSON序列化,但这对我没有帮助,因为我需要无法从C#属性名称推断的JSON属性名称。
我还希望能够为页面本身设置自定义JSON属性名称。
我真的希望友好的EpiServer大师可以帮助我在这里!
提前致谢:)
答案 0 :(得分:1)
我项目中的一个C#开发人员最终为此推出了自己的解决方案。他使用反射来检查页面树并从中构建JSON。这里是。希望它能像对待我一样帮助别人!
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.ServiceLocation;
using EPiServer.Web.Mvc;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Dynamic;
using System.Reflection;
using System;
using System.Runtime.Caching;
using System.Linq;
using Newtonsoft.Json.Linq;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
namespace NUON.Models.MyCorp
{
public class MyCorpPageController : PageController<MyCorpPage>
{
public string Index(MyCorpPage currentPage)
{
Response.ContentType = "text/json";
// check if the JSON is cached - if so, return it
ObjectCache cache = MemoryCache.Default;
string cachedJSON = cache["myCorpPageJson"] as string;
if (cachedJSON != null)
{
return cachedJSON;
}
var output = new ExpandoObject();
var outputDict = output as IDictionary<string, object>;
var pageRouteHelper = ServiceLocator.Current.GetInstance<EPiServer.Web.Routing.PageRouteHelper>();
var pageReference = pageRouteHelper.PageLink;
var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
var children = contentLoader.GetChildren<PageData>(currentPage.PageLink).OfType<PageData>();
var toOutput = new { };
var jsonResultObject = new JObject();
foreach (PageData page in children)
{
// Name = e.g. BbpbannerProxy . So remove "Proxy" and add the namespace
var classType = Type.GetType("NUON.Models.MyCorp." + page.GetType().Name.Replace("Proxy", string.Empty));
// Only keep the properties from this class, not the inherited properties
jsonResultObject.Add(page.PageName, GetJsonObjectFromType(classType, page));
}
// add to cache
CacheItemPolicy policy = new CacheItemPolicy();
// expire the cache daily although it will be cleared whenever content changes.
policy.AbsoluteExpiration = DateTimeOffset.Now.AddDays(1.0);
cache.Set("myCorpPageJson", jsonResultObject.ToString(), policy);
return jsonResultObject.ToString();
}
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule),
typeof(EPiServer.Web.InitializationModule))]
public class EventsInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
var events = ServiceLocator.Current.GetInstance<IContentEvents>();
events.PublishedContent += PublishedContent;
}
public void Preload(string[] parameters)
{
}
public void Uninitialize(InitializationEngine context)
{
}
private void PublishedContent(object sender, ContentEventArgs e)
{
// Clear the cache because some content has been updated
ObjectCache cache = MemoryCache.Default;
cache.Remove("myCorpPageJson");
}
}
private static JObject GetJsonObjectFromType(Type classType, object obj)
{
var jsonObject = new JObject();
var properties = classType.GetProperties(BindingFlags.Public
| BindingFlags.Instance
| BindingFlags.DeclaredOnly);
foreach (var property in properties)
{
var jsonAttribute = property.GetCustomAttributes(true).FirstOrDefault(a => a is JsonPropertyAttribute);
var propertyName = jsonAttribute == null ? property.Name : ((JsonPropertyAttribute)jsonAttribute).PropertyName;
if (property.PropertyType.BaseType == typeof(BlockData))
jsonObject.Add(propertyName, GetJsonObjectFromType(property.PropertyType, property.GetValue(obj)));
else
{
var propertyValue = property.PropertyType == typeof(XhtmlString) ? property.GetValue(obj)?.ToString() : property.GetValue(obj);
if (property.PropertyType == typeof(string))
{
propertyValue = propertyValue ?? String.Empty;
}
jsonObject.Add(new JProperty(propertyName, propertyValue));
}
}
return jsonObject;
}
}
[ContentType(DisplayName = "MyCorpPage", GroupName = "MyCorp", GUID = "bc91ed7f-d0bf-4281-922d-1c5246cab137", Description = "The main MyCorp page")]
public class MyCorpPage : PageData
{
}
}
答案 1 :(得分:0)
您好我正在寻找相同的东西,直到现在我找到了这个页面和组件。 https://josefottosson.se/episerver-contentdata-to-json/
https://github.com/joseftw/JOS.ContentJson
我希望你觉得它很有用