"You cannot save a class that does not contain a property that represents the item ID" 当 GlassCast(ing) 分支模板项时,为什么?
"You cannot save a class that does not contain a property that represents the item ID" when GlassCast(ing) a branch template item, why?
我一整天都在为这个问题苦苦思索,运行 没主意了。基本上是因为 glass.mapper 似乎不支持分支模板,所以我正在使用标准数据库方法创建一个 sitecore 项目。然后我使用 GlassCast<T>()
给我一个正确类型的对象。
此类型化对象似乎包含一个 id 字段,但是,当我尝试保存该对象时出现错误:
You cannot save a class that does not contain a property that
represents the item ID
这是我的方法:
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);
}
有效!
有人知道我做错了什么吗?
终于到了。这个问题实际上并不包含缺失的部分,但我会给出一个答案,以防其他人陷入这个问题 cul-de-sac!
我的问题实际上是具体的 class。我没有注意到的是 class 中还包含其他 classes:
public class V2Development : ICmsItem
{
.....
[SitecoreField]
public virtual IEnumerable<CallToActionButtonBase> CallToActionButtons { get; set; }
}
CallToActionButtonBase
类型没有 ID
字段!所以 glass mapper 正在沿着整个依赖关系树工作,并试图解析所有 objects。然后当它碰到这个时,它失败了,因为它没有 id( 下次我们能不能有一个更具建设性的错误消息,请 GlassMapper 先生?比如说哪个 object 丢失了id?)
我的解决办法是添加一个抽象层,所以我有两个 object,一个有 children,一个没有。然后我创建了一个没有 children 的 object 的实例(接口会完成类似的工作,但是,TBH,这个解决方案在接口中游泳,我试图避免再使用)。
如果有人将 GlassMapper 的可编辑助手 class 与没有关联 ID 属性的模型 属性 一起使用,则会出现同样的问题。
解决这个问题的最简单方法是声明一个 ID 为 属性 的接口并继承它(如果你已经有一个,你可以将它添加到你的基类型)。
[SitecoreType]
public interface ISitecoreItem
{
[SitecoreId]
Guid ID { get; set; }
[SitecoreInfo(Type = SitecoreInfoType.TemplateId)]
Guid TemplateID { get; set; }
[SitecoreInfo(Type = SitecoreInfoType.TemplateName)]
string TemplateName { get; set; }
[SitecoreInfo(Type = SitecoreInfoType.Path)]
string Path { get; set; }
}
然后在Component/Page具体机型中继承上述内容
public interface ISiteWide : ISitecoreItem
{
//Component specific properties goes here
}
我一整天都在为这个问题苦苦思索,运行 没主意了。基本上是因为 glass.mapper 似乎不支持分支模板,所以我正在使用标准数据库方法创建一个 sitecore 项目。然后我使用 GlassCast<T>()
给我一个正确类型的对象。
此类型化对象似乎包含一个 id 字段,但是,当我尝试保存该对象时出现错误:
You cannot save a class that does not contain a property that represents the item ID
这是我的方法:
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);
}
有效!
有人知道我做错了什么吗?
终于到了。这个问题实际上并不包含缺失的部分,但我会给出一个答案,以防其他人陷入这个问题 cul-de-sac!
我的问题实际上是具体的 class。我没有注意到的是 class 中还包含其他 classes:
public class V2Development : ICmsItem
{
.....
[SitecoreField]
public virtual IEnumerable<CallToActionButtonBase> CallToActionButtons { get; set; }
}
CallToActionButtonBase
类型没有 ID
字段!所以 glass mapper 正在沿着整个依赖关系树工作,并试图解析所有 objects。然后当它碰到这个时,它失败了,因为它没有 id( 下次我们能不能有一个更具建设性的错误消息,请 GlassMapper 先生?比如说哪个 object 丢失了id?)
我的解决办法是添加一个抽象层,所以我有两个 object,一个有 children,一个没有。然后我创建了一个没有 children 的 object 的实例(接口会完成类似的工作,但是,TBH,这个解决方案在接口中游泳,我试图避免再使用)。
如果有人将 GlassMapper 的可编辑助手 class 与没有关联 ID 属性的模型 属性 一起使用,则会出现同样的问题。 解决这个问题的最简单方法是声明一个 ID 为 属性 的接口并继承它(如果你已经有一个,你可以将它添加到你的基类型)。
[SitecoreType]
public interface ISitecoreItem
{
[SitecoreId]
Guid ID { get; set; }
[SitecoreInfo(Type = SitecoreInfoType.TemplateId)]
Guid TemplateID { get; set; }
[SitecoreInfo(Type = SitecoreInfoType.TemplateName)]
string TemplateName { get; set; }
[SitecoreInfo(Type = SitecoreInfoType.Path)]
string Path { get; set; }
}
然后在Component/Page具体机型中继承上述内容
public interface ISiteWide : ISitecoreItem
{
//Component specific properties goes here
}