2016-07-14 55 views
0

我完全新的EpiServer,這已經殺了我好幾天:(連載整個頁面樹JSON在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; 
    } 
} 

的問題是,通過轉換頁面結構,字典,在我的網頁上JsonProperty屬性名的註釋丟失:

[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

您可以更新您的問題,包括的toJSON實施,以及,一個建議,我會做的是改變'詞典<字符串,對象>'來'詞典<字符串,MySubPage>' – din

+0

我只是用'outputDict .ToJson();'在Index方法的末尾。關於你的建議,我可以這樣做我猜:'var newStruct = new Dictionary ();' 雖然我不確定這會有幫助嗎? –

+0

更新:我現在嘗試了JOS.Content.Json。希望這會有所幫助。如果是這樣,我會發布我的解決方案。 https://github.com/joseftw/JOS.ContentJson –

回答

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 
    { 
    } 
}