2016-02-02 77 views
5

我正在嘗試在Kentico(v8.2.x或v9.0)中編寫適當緩存的單個宏方法,並公開了一些POCO 。訪問Kentico自定義對象宏方法中的嵌套屬性

在Visual Studio中調試,我可以看到查詢運行正常,並且對象實例返回完全如何我想要的。此外,使用Kentico中的Debug應用程序檢查緩存的項目也會顯示完整的POCO實例數據按預期緩存。

但是,當調用宏時,我似乎只能讀取對象的字符串表示形式。

這是一個擴展CurrentUserInfo類型的宏,所以我嘗試調用它像這樣:

{% CurrentUser.ClientStatus() %} 

但嘗試檢索任意嵌套屬性的失敗。

我相信這只是我沒有做某事(如正確註冊這些屬性)。但從documentation,我看到很多東西,它可能是。例如:

  • 命名來源
  • 命名回調源
  • 匿名消息來源
  • 或登記他們作爲獨立的領域在某種程度上

這裏是宏本身:

/// <summary> 
/// A class containing custom user-extension macros. 
/// </summary> 
[assembly: RegisterExtension(typeof(CustomUserMacros), typeof(CurrentUserInfo))] 
public class CustomUserMacros : MacroMethodContainer 
{ 
    /// <summary> 
    /// Retrieves data regarding user client. 
    /// </summary> 
    /// <param name="context">The context.</param> 
    /// <param name="parameters">The parameters.</param> 
    /// <returns>Data regarding user client information.</returns> 
    [MacroMethod(typeof(ClientInfo), "Retrieves client info.", 1)] 
    [MacroMethodParam(0, "user", typeof(CurrentUserInfo), "The user.")] 
    public static object ClientStatus(
      EvaluationContext context, 
      params object[] parameters) 
    { 
     ClientInfo retVal = null; 
     if (parameters != null && parameters.Length > 0 
       && parameters[0].GetType() == typeof(CurrentUserInfo)) 
     { 
      var siteName = SiteContext.CurrentSiteName; 
      var userGuid = ((CurrentUserInfo)parameters[0]).UserGUID; 
      var uInfo = UserInfoProvider.GetUserInfoByGUID(userGuid); 
      retVal = CacheHelper.Cache(
       cs => new ClientInfo(uInfo, siteName), 
       new CacheSettings(
        60, 
        typeof(CustomUserMacros), 
        "ClientStatus", 
        userGuid)); 
     } 

     return retVal; 
    } 
} 

ClientInfo cl屁股是非常直接的:

public class ClientInfo 
{ 
    public string Summary { get; private set; } 

    public CustomTableItem ClientRecord { get; private set; } 

    public IEnumerable<string> MediaPaths { get; private set; } 

    public ClientInfo(UserInfo userInfo, string siteCodeName) { 
     // ... 
     // Set properties, etc... 
    } 

    public override string ToString() 
    { 
     return Summary; 
    } 
} 

什麼是最容易的方式來訪問屬性,以類似於以下方式?

{% CurrentUser.ClientStatus().ClientRecord["< Column Name >"] %} 
+0

在進一步閱讀,我覺得在我的情況下,這一切可能是最好關閉自定義模塊,而不是英寸不過,我會在這裏留下問題,因爲我喜歡K#宏,而且我相信瞭解如何才能使上述工作起作用仍然很有用! – ne1410s

+0

好問題!關於宏的文檔有點複雜,但這確實解決了我過去遇到的一些問題。 –

回答

5

爲了能夠在你所描述的方式來訪問屬性,父對象必須是DataRowDataRowView型或實施的一個以下接口:IVirtualHierarchicalObjectIHierarchicalObject,IDataContainer, ISimpleDataContainer

在你的情況下,ClientInfo應該實現IDataContainer。嵌套的CustomTableItem已經實現了其中一個接口,因爲它從AbstractInfo繼承。

你必須要實現幾個成員主要有參數工作稱爲columnName確定其值的成員,您應該返回:

public class ClientInfo : IDataContainer 
{ 
    ... 
    public object GetValue(string columnName) 
    { 
     switch (columnName) 
     { 
      case "ClientRecord": 
       return ClientRecord; 

      case "Summary": 
       return Summary; 

      case "MediaPaths": 
       return MediaPaths; 
     } 
     return null; 
    } 
    ... 
} 
+0

我實現了所有的接口成員('set'除外),它就像一個魅力!非常感謝 – ne1410s

-2

所有我建議你使用系統的第一個 - >宏 - >命令來測試您的宏 - 它非常有用。 你的情況,你應該能夠訪問這樣的屬性:

{% CurrentUser.ClientStatus().Summary %} 
0

很可能不能在這種情況下工作過,但值得一提的還有那您可以使用CMS.Base.DataContainerIEnumerable<CMS.Base.DataContainer>返回簡單對象的值:

return myCollection.Select(myObj => new DataContainer 
       { 
        ["Value1"] = myObj.Value1, 
        ["Value2"] = myObj.Value2 
       });