如何根据ContentArea的类型从ContentArea获取块项

时间:2018-04-04 16:23:16

标签: c# episerver

我有一个页面类型,其中ContentArea作为其属性之一

(currentPage.PrimaryComponentArea)

如何根据类型获取存储在此属性中的块项目。

我还想访问块上的属性,所以我需要将它从ContentAreaItem转换为actuall块类型。

        public ActionResult Index(RatePlanPageType currentPage)
        {
          ..........

          var allItems = currentPage.PrimaryComponentArea.Items;

          var blocks = allItems.Where(x => bla bla bla  < Can I do it using linq

        }

这是我的第一个Episerver项目,所以我希望这不是一个愚蠢的问题。

3 个答案:

答案 0 :(得分:2)

var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
if (page != null && page.ContentArea != null && page.PrimaryComponentArea.Items.Any())
{
    foreach (var contentItem in page.PrimaryComponentArea.Items)
    {
        var item = contentLoader.Get<YOUR_CONTENT_TYPE>(contentItem.ContentLink);
        // do your stuff
    }
}

ContentArea中的项目保存为ContentReference,所有ContentReference都引用IContent。块和页面类型是IContent。

如果要将contentareas限制为一种类型:[AllowedTypes(new [] {typeof(PageData),typeof(BlockData)})]

https://world.episerver.com/documentation/Items/Developers-Guide/Episerver-CMS/9/Content/Properties/Property-types/Restricting-content-types-in-properties/

答案 1 :(得分:0)

        var resultList = new List<IContent>();
        var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

        foreach (ContentAreaItem contentAreaItem in currentPage.PrimaryComponentArea.FilteredItems)
        {
            if (contentAreaItem != null && contentAreaItem.ContentLink != null &&
                contentAreaItem.ContentLink != ContentReference.EmptyReference)
            {

            IContent content;
            if (contentLoader.TryGet(contentAreaItem.ContentLink, out content))
                if (content != null)
                {
                    resultList.Add(content);
                }
            }
        }

上面的代码将为您提供contentarea中的块列表作为IContent。请注意,我使用了FilteredItems,它也考虑了任何个性化,发布状态等。

要访问块的属性,您需要将它们转换为类型。 所以这样的事情可能会指向正确的方向

  foreach (IContent content in resultList)
    {
                var block = content as YourBlockType;
                if (content != null)
                {
                    // the content is of type YourBlockType. Do work 
                }
    }

答案 2 :(得分:0)

使用linq解决此问题

// ServiceLocator as example, use dependency injection!
var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

// Get all CodeBlock's from the contentarea
IEnumerable<CodeBlock> items = currentPage.ContentArea?.Items?
    .Where(block => block.GetContent() is CodeBlock) // validate type
    .Select(block => contentLoader.Get<CodeBlock>(block.ContentLink));

// Run a where on a specific property on the blocks
IEnumerable<CodeBlock> items = currentPage.ContentArea?.Items?
    .Where(block => block.GetContent() is CodeBlock) // validate type
    .Select(block => contentLoader.Get<CodeBlock>(block.ContentLink))
    .Where(block => block.Tags.Contains("Episerver"));

现在的诀窍是使用.Where(block => block.GetContent() is CodeBlock)block.GetContent()会解析一个允许你验证块类型的IContent对象

对于更通用的方法,请使用此

IEnumerable<IContent> items = currentPage.ContentArea?.Items?
    .Select(content => contentLoader.Get<IContent>(content.ContentLink))  // Get as IContent
    .Where(content => content.Name.Contains("block")); // any properties you like

最后一个版本还将包含页面,如果它们被删除在contentarea中,如果您只想支持特定类型使用相同的类型验证

IEnumerable<IContent> items = currentPage.ContentArea?.Items?
    .Where(content => content.GetContent() is BlockData) // validate type
    .Select(content => contentLoader.Get<IContent>(content.ContentLink))
    .Where(content => content.Name.Contains("block"));

在使用空传播时,始终检查变量是否为null {I} ContentArea?.Items?...

if(items != null) {
    // Yay!
}