2016-02-02 2 views
5

Я пытаюсь написать один метод макроса в Kentico (v8.2.x или v9.0), который кэшируется соответствующим образом, и предоставляет POCO с несколькими открытыми членами ,Доступ к вложенным свойствам в методе макрокоманды настраиваемого объекта Kentico

Отладка в Visual Studio, я вижу, что запрос работает нормально, и экземпляр объекта возвращается именно так, как я хочу. Кроме того, проверка кэшированных элементов с использованием приложения Debug в Kentico также показывает, что данные экземпляра POCO кэшируются, как ожидалось.

Однако при вызове макроса я, по-видимому, способен читать строковое представление объекта.

Это макрос, который расширяет CurrentUserInfo тип, поэтому я пытаюсь вызвать его, как это:

{% CurrentUser.ClientStatus() %} 

Но попытки получить любой из вложенных свойств не удается.

Уверен, что я ничего не сделал (например, зарегистрируйте эти свойства правильно). Но от documentation я видел много вещей, которые он мог be. Например:

  • неназванный источник
  • Названный источник обратного вызова
  • Анонимный источник
  • Или зарегистрировав их как отдельные поля как-то

Вот сам макрос:

/// <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

Чтобы иметь возможность получить доступ к свойствам, как вы описали, родительский объект должен иметь DataRow или DataRowView типа или реализации одного из следующие интерфейсы: IVirtualHierarchicalObject, IHierarchicalObject, 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

Прежде всего, я бы рекомендовал вам использовать System -> Macros -> Console для проверки вашего макроса - это очень полезно. В вашем случае вы должны быть в состоянии получить доступ к свойствам, как это:

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

Вероятно, не работал бы в этом случае, но стоит отметить также, что вы можете вернуть простые значения объекта с помощью CMS.Base.DataContainer или IEnumerable<CMS.Base.DataContainer>:

return myCollection.Select(myObj => new DataContainer 
       { 
        ["Value1"] = myObj.Value1, 
        ["Value2"] = myObj.Value2 
       }); 
Смежные вопросы