Hard to say where it might fail but I would do your code a bit differently and you eliminate all "index out of bounds" possibilites :)
var contentAreaItems = Model.Content.FilteredItems.Take(blockMaxCount); foreach (var item in contentAreaItems) { var block = item.GetContent(); if (block is ArticlePromoBlock) { var articlePromoBlock = block as ArticlePromoBlock; // do stuff } else if (block is NewsPromoBlock) { // similar as above } }
Make sure Models.Content isn't null.
Thanks Mikael. I've altered it to your better structure but unfortunately it's still crashing IIS when it hits the Html.RenderAction. The IIS issue might be too hard to diagnose in a forum like this so I guess the crux of my question is how do people do this? Has someone got something like the following code to work before?
var contentAreaItems = Model.Content.FilteredItems.Take(5); foreach (var item in contentAreaItems) { var block = item.GetContent(); if (block is ArticlePromoBlock) { var articlePromoBlock = block as ArticlePromoBlock; Html.RenderAction("Index", "ArticlePromoBlock", articlePromoBlock); } }
Can you fill out the context a little bit more, what are you trying to achieve and why handle the contentarea items "manually" instead of using PropertyFor?
So we are creating layout blocks that from a dropdown can choose various configurations.
e.g. 2/3/4 column & 2 column split layout (shows 1 large block on 1 side and 4 small blocks on the other)
So with the 2 column split layout block, our issue is we want to render the first block differently than the other 4 that will make up the second column.
Our aim is to just have the one layout block for all these layouts to make it easier for the user. I'm also trying to avoid having more than one ContentArea due to it only applying to a few of the layouts.
Could you please post what error message you get? I've done something similiar...I don't have access to the code right now though but will post when Im back at the office
As content area items are not handled by ordinary controllers (like it's done for pages), but they are child action controllers - you should not call RenderAction directly. This will try to call controller that is handling blocks as Mvc controller.
Haven't tried myself, just a wild guess (so it may could fail) - try to go through content data extensions to render that content:
EPiServer.Web.Mvc.Html.IContentDataExtensions.RenderContentData(htmlHelper, articlePromoBlock, true);
Thanks everyone! The missing peice of the puzzle was the line Valdis posted. Here's the final working version incase someone else is interested.
@{ var contentAreaItems = Model.Content.FilteredItems.Take(5); foreach (var item in contentAreaItems) { var block = item.GetContent(); Html.RenderContentData(block, true); } }
Using this way I could just pass the content as is without the unwieldy 'if' chain, used to set the specific model.
EDIT: Sanitised RenderContentData line
Hi,
I have been trying to find a way to iterate through a number of block's with various types. As a guide I followed the similar thread here that helped with iterating through blocks of the same type.
Ideally I would like to write a helper function that would return the rendered content of a ContentAreaItem. For now though here's the code I have at the moment but it crashes IIS when it run's.
A number of us at my work have tried to solve this problem at different times, so any help would be greatly appriciated!
Cheers Ben