Try our conversational search powered by Generative AI!

ContentArea rendering ViewModels?

Vote:
 

If I want to render a couple of blocks on the page, I would define a ContentArea:

        [Display(
            GroupName = SystemTabNames.Content,
            Order = 320)]
        [CultureSpecific]
        public virtual ContentArea MainContentArea { get; set; }

This content area "knows" how to render the blocks, if their model is, let's say, EditorialBlock2 - which eventually inherits from EPiServer.Core.BlockData.

However, if I define a EditorialBlock2ViewModel, and add @model PROJECT.Web.Views.Shared.EditorialBlock2ViewModel to EditorialBlock2.cshtml, I get the following error:

The model item passed into the dictionary is of type 'Castle.Proxies.EditorialBlock2Proxy', but this dictionary requires a model item of type 'PROJECT.Web.Views.Shared.EditorialBlock2ViewModel'.

The controller looks like this:

public ActionResult EditorialBlock2(EditorialBlock2 currentBlock)
{
var viewModel = new EditorialBlock2ViewModel();
AutoMapper.Mapper.Map(currentBlock, viewModel);

return PartialView(viewModel);
}

This is how MainContentArea on the page looks like:

@Html.PropertyFor(m => m.MainContentArea, new { CssClass = "row equal-height" })

Is there a way to make this work? Would I need to have @Html.RenderAction that creates a list of ViewModels of specific types? Than I wouldn't be able to add blocks of random type?

 
#64319
Dec 17, 2012 18:32
Vote:
 

I think you are being tricked by an implemented Index action defined in a base class of BlockController<T>. Are you inheriting from BlockController<T>? Try to rename your action to

public override ActionResult Index(EditorialBlock2 currentBlock){...}

 

If you are only mapping propertied from the Block type to the View Model, you could skip the Controller completely and create a view (using the BlockType as model directly) and place the view in the View/Shared folder. Name the view EditorialBlock2.cshtml.

/Sørby

 

#64323
Dec 18, 2012 0:22
Vote:
 

Hi, Petter,

Thank you very much for your answer! It solved my problem.

This is how the controller looks like now:

public override ActionResult Index(EditorialBlock2 currentBlock)
{
var viewModel = new EditorialBlock2ViewModel();
AutoMapper.Mapper.Map(currentBlock, viewModel);

return PartialView("EditorialBlock2", viewModel);
}

 

I prefer to have a ViewModel, this is just for a base code, most probably in the real world, I would do some other stuff, other than just mapping.

 

#64335
Dec 18, 2012 9:57
Vote:
 

Hi,

I'd just like to add that only having a partial view like Petter described won't only result in less code but also significantly better performance as having the controller means the block will be rendered with RenderAction and thereby forcing a full "MVC cycle" for each block on a page.

The most pragmatic way always depends on the unique case for each site of course, but I thought it would be good to mention in this thread as the performance implications may not be obvious.

#64338
Dec 18, 2012 10:47
Vote:
 

Thx a lot for your valuable input, Joel.

I think it would be good to use this approach, for example, when having Image block (with only ImageUrl and ImageAlt), than there is no need to do only mapping.

#64373
Dec 18, 2012 15:45
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.