在 Orchard CMS 中,我正在尝试创建一个自定义字段,它是分类字段的“扩展”。
到目前为止,我只是创建了另一个字段,并且基本上复制了运行分类字段的所有代码 - 当我将普通分类字段和我的自定义分类字段附加到内容类型时,它实际上可以工作。我的自定义字段中选定的术语保存并按预期工作。
当我删除标准分类字段并仅使用我的自定义字段时,我遇到了问题。这是因为不再有必需的 TermsPart 被焊接到内容项上。记录的错误是:
Orchard.ContentManagement.Drivers.Coordinators.ContentFieldDriverCoordinator - NullReferenceException thrown from <>f__AnonymousType4`2 by <>f__AnonymousType4`2[[Orchard.ContentManagement.ContentPart, Orchard.Framework, Version=1.7.1.0, Culture=neutral, PublicKeyToken=null],[Fusion.ContentTiles.Fields.TaxonomyTileField, Fusion.ContentTiles, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
System.NullReferenceException: Object reference not set to an instance of an object.
at Orchard.Taxonomies.Services.TaxonomyService.UpdateTerms(ContentItem contentItem, IEnumerable`1 terms, String field)
at Fusion.ContentTiles.Drivers.TaxonomyTileFieldDriver.Editor(ContentPart part, TaxonomyTileField field, IUpdateModel updater, Object shapeHelper)
at Orchard.ContentManagement.Drivers.ContentFieldDriver`1.<>c__DisplayClass13.<Orchard.ContentManagement.Drivers.IContentFieldDriver.UpdateEditorShape>b__12(ContentPart part, TField field) in c:\Projects\Demos\Orchard\src\Orchard\ContentManagement\Drivers\ContentFieldDriver.cs:line 47
at Orchard.ContentManagement.Drivers.ContentFieldDriver`1.<>c__DisplayClass2d.<Process>b__2b(<>f__AnonymousType4`2 pf) in c:\Projects\Demos\Orchard\src\Orchard\ContentManagement\Drivers\ContentFieldDriver.cs:line 86
at Orchard.InvokeExtensions.<Invoke>d__0`2.MoveNext() in c:\Projects\Demos\Orchard\src\Orchard\InvokeExtensions.cs:line 39
当我设置断点并查看 TaxonomyService 时,当它尝试将内容项加载为 TermsPart 时,它返回 null,从而抛出 NRE。
我不完全确定如何将这个 TermsPart 焊接到内容项上。我猜我需要在某种处理程序中执行此操作,但我无法解决这个问题。只要看看我的代码,我就知道它是错误的,真的需要用一个例子或其他东西指出正确的方向。
我的非工作处理程序(离它太远了,甚至没有达到断点):
public class TaxonomyTileFieldHandler : ContentHandler {
private readonly IContentDefinitionManager _contentDefinitionManager;
public TaxonomyTileFieldHandler(
IContentDefinitionManager contentDefinitionManager) {
_contentDefinitionManager = contentDefinitionManager;
}
protected override void Activating(ActivatingContentContext context) {
base.Activating(context);
// weld the TermsPart dynamically, if a field has been assigned to one of its parts
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentType);
if (contentTypeDefinition == null) {
return;
}
if (contentTypeDefinition.Parts.Any(
part => part.PartDefinition.Fields.Any(
field => field.FieldDefinition.Name == typeof(TaxonomyTileField).Name))) {
context.Builder.Weld<TermsPart>();
}
}
}
我还没有尝试在现场驱动程序中焊接零件……但这似乎太错误了(这就是为什么我还没有尝试它的原因)。
我的问题是:如何将零件焊接到带有字段的内容项上?