Вы не можете сохранить класс, который не содержит свойства, представляющего идентификатор элемента, когда GlassCast(инг) элемент шаблона ветви, почему?

Я бьюсь об это головой весь день, и у меня закончились идеи. В основном потому, что Glass.mapper не поддерживает шаблоны веток, я создаю элемент sitecore, используя стандартные методы БД. Затем я использую GlassCast<T>(), чтобы получить правильно типизированный объект.

Этот типизированный объект, по-видимому, содержит поле идентификатора, однако, когда я пытаюсь сохранить объект, я получаю сообщение об ошибке:

Вы не можете сохранить класс, который не содержит свойства, представляющего идентификатор элемента.

Вот мой метод:

private Glass.Mapper.Sc.ISitecoreService SitecoreService;

public T CreateFromBranch<T>(string parentPath, string itemName,
            Guid branchTemplateId) where T : class, ICmsItem
{

    Item parent = SitecoreService.Database.GetItem(parentPath);//SitecoreService.GetItem<Item>(parentPath);
    if (parent == null)
        throw new NullReferenceException("Cannot load item to act as parent from path: " + parentPath);

    BranchItem branch = SitecoreService.Database.GetItem(new ID(branchTemplateId));
    if (branch == null)
        throw new ApplicationException("Failed ot find template branch with the id:" + branchTemplateId);

    Item itemFromBranch = parent.Add(itemName, branch);                   
    if (itemFromBranch == null)
        throw new ApplicationException("Failed to create item from branch template. BranchId: " + branchTemplateId);


    itemFromBranch.Fields.ReadAll();


    T typedItem  = itemFromBranch.GlassCast<T>();
    //Id is accessible here and is the id of the item that is created!
    Guid id = typedItem.Id;
    typedItem.DisplayName = itemDisplayName;

    //Exception thrown here!
    SitecoreService.Save(typedItem);

    return typedItem;
}

Интерфейс:

[SitecoreType(AutoMap = true)]
public interface ICmsItem
{
    //Id flagged here! Same in the concrete class
    [SitecoreId]
    Guid Id { get; }

    [SitecoreInfo(SitecoreInfoType.Name)]
    string Name { get; set; }

    [SitecoreInfo(SitecoreInfoType.DisplayName)]
    string DisplayName { get; set; }

    [SitecoreInfo(SitecoreInfoType.Path)]
    string Path { get; set; }

    [SitecoreInfo(SitecoreInfoType.TemplateId)]
    Guid TemplateId { get; set; }

    [SitecoreField(FieldName = "__Never publish")]
    bool NeverPublish { get; set; }

    [SitecoreField(FieldName = "__Icon")]
    string CmsIcon { get; set; }

    [SitecoreField(FieldName = "__Workflow")]
    Guid? Workflow { get; set; }

    [SitecoreField(FieldName = "__Workflow state")]
    Guid? WorkflowState { get; set; }

    [SitecoreField(FieldName = "__Sortorder")]
    int SortOrder { get; set; }
}

элемент создается в sitecore. Но у него нет обновленного отображаемого имени. Если я изменю код так, чтобы он вообще не использовал стеклянный картограф:

if (!string.IsNullOrWhiteSpace(itemDisplayName))
{
     itemFromBranch.EditField("__Display name", itemDisplayName);
}

Оно работает!

Кто-нибудь понял, что я здесь делаю неправильно?


person Liam    schedule 02.11.2015    source источник
comment
Можете ли вы попробовать добавить модификатор set к свойству Id, чтобы увидеть, имеет ли это какое-то значение.   -  person jammykam    schedule 02.11.2015
comment
Хорошая идея @jammykam, но, похоже, это не имеет значения. Теперь я полностью исключил интерфейс из уравнения и ввожу его в конкретный класс. Все та же проблема   -  person Liam    schedule 02.11.2015
comment
Извините, в голову не пришло, вроде все в порядке. Лично я бы не стал использовать Glass только для обновления поля, ваш рабочий образец без использования Glass в порядке, IMO. Работает ли возврат литого объекта в соответствии с этим кодом?   -  person jammykam    schedule 02.11.2015
comment
Я не просто обновляю это поле. Я обновляю почти все поля. Это просто укороченный пример. В итоге добрался, спасибо за помощь @jammykam   -  person Liam    schedule 02.11.2015
comment
Здорово, рад, что удалось докопаться до сути!   -  person jammykam    schedule 02.11.2015


Ответы (1)


Добрался в итоге. На самом деле вопрос не содержит недостающей части, но я даю ответ на случай, если кто-то еще застрял в этом тупике!

Мои проблемы были на самом деле конкретным классом. Чего я не заметил, так это того, что в этом классе были другие классы:

public class V2Development : ICmsItem
{
    .....
    [SitecoreField]
    public virtual IEnumerable<CallToActionButtonBase> CallToActionButtons { get; set; }
}

Тип CallToActionButtonBase не имеет поля ID! Таким образом, Glass Mapper спускался по всему дереву зависимостей и пытался разрешить все объекты. Затем, когда он столкнулся с этим, он потерпел неудачу, потому что у него не было идентификатора (не могли бы мы в следующий раз создать более конструктивное сообщение об ошибке, пожалуйста, мистер GlassMapper? Например, скажите, у какого объекта отсутствует идентификатор? )

Мое исправление состояло в том, чтобы добавить слой абстракции, поэтому у меня есть два объекта, один с дочерними элементами, а другой без. Затем я создаю экземпляр объекта без дочерних элементов (интерфейс выполнил бы аналогичную работу, но, TBH, это решение плавает в интерфейсах, и я стараюсь больше не использовать).

person Liam    schedule 02.11.2015
comment
отправил ветку с помощью glass.mapper, чтобы попытаться сделать это сообщение об ошибке более полезным - person Liam; 02.11.2015