Umbraco ModelsBuilder - 如何从子节点获取强类型对象

Umbraco ModelsBuilder - How to get strongly typed objects from child nodes

我正在使用 Umbraco 的 ModelsBuilder 从我的文档类型生成强类型模型以用于我的代码。

这工作得很好,但我想知道如何为任何给定生成模型的子项获取强类型对象。

这是一个例子:

public ActionResult Index(HomePage model)
{
    var components = model
        .Children.Where(x => x.DocumentTypeAlias == PageComponentsFolder.ModelTypeAlias)
        .Single().Children; 
}

HomePage 是由 Umbraco 模型生成器生成的强类型 class。在主页节点下,我有一个页面组件文件夹,其中包含几个其他节点,它们都继承自 ComponentsBaseClass。

如何使我的组件在强类型对象列表之上成为变量。

这可能吗?

好的,这就是我最终得到的结果,这里是一个如何使用由 Umbraco 模型绑定器生成的强类型模型的示例。

var components = model.Children
    .Where(x => x.DocumentTypeAlias == PageComponentsFolder.ModelTypeAlias)
    .Single().Children; 

foreach (var component in components)
{    
    string componentNodeTypeAlias = component.DocumentTypeAlias;

    switch (componentNodeTypeAlias)
    {
        case SimpleHero.ModelTypeAlias:
            Html.Partial("component_simpleHero", component as SimpleHero)
            break;

        case VideoWithHtml.ModelTypeAlias:
            Html.Partial("component_videoWithHTML", component as VideoWithHtml)
            break;
    }
}

您可以像这样在 Umbraco 中定位 children 特定类型:

IEnumerable<YourModel> childrenOfType = model.Children<YourModel>();

这将return所有children类型为YourModel 的模型—— 它本质上结合了一个Where()和一个Cast<T>()

回答你"is this possible"的问题,答案是否定的。

你不能拥有你想要的那种 "strongly typed list of objects" 因为在 C# 中列表(或其他 IEnumerable)总是一个常见类型的列表,例如List<ACommonType>。在 Umbraco 的情况下,它们都共享 IPublishedContent 的接口。您可以遍历该列表并计算出每个 object 的实际类型。在 Umbraco 中,列表中的 IPublishedContent 实际上并不使用 ModelsBuilder 中的类型,直到您转换它们。

foreach(IPublishedContent c in collectionOfIPublishedContent)
{
    // basic if
    if (c.DocumentTypeAlias == YourModel.ModelTypeAlias)
    {
        YourModel stronglyTypedContent = c as YourModel;
        // do some stuff
    }

    // or switch...
    switch (c.DocumentTypeAlias)
    {
        case YourModel.ModelTypeAlias:
            YourModel stronglyTypedContent2 = c as YourModel;
            // do a thing
            break;
    }

    // or use implicit casts with null checking
    YourModel stronglyTypedContent3 = c as YourModel;
    if (stronglyTypedContent3 != null)
    {
        // congrats, your content is of the type YourModel
    }
}