EpiServer - Add block to a content area programmatically
Asked Answered
S

1

7

I have a content area which will have some blocks, some attributes of these blocks must be initialized with data from a SQL query, so in the controller I have something like this:

foreach (ObjectType item in MyList)
{
    BlockData currentObject = new BlockData
    {
        BlockDataProperty1 = item.ItemProperty1,
        BlockDataProperty2 = item.ItemProperty2
    };
    /*Dont know what to do here*/
}

What I need, is to work with currentObject as a block, and add it to a content area I have defined in another block. I tried using

myContentArea.Add(currentObject)

but it says it can't add an object into a content area because it is expecting for an IContent type.

How can I cast that object into an IContent?

Sarcastic answered 16/1, 2015 at 22:40 Comment(0)
B
11

To create content in EPiServer you need to use an instance of IContentRepository instead of new operator:

var repo = ServiceLocator.Current.GetInstance<IContentRepository>();

// create writable clone of the target block to be able to update its content area
var writableTargetBlock = (MyTargetBlock) targetBlock.CreateWritableClone();

// create and publish a new block with data fetched from SQL query
var newBlock = repo.GetDefault<MyAwesomeBlock>(ContentReference.GlobalBlockFolder);

newBlock.SomeProperty1 = item.ItemProperty1;
newBlock.SomeProperty2 = item.ItemProperty2;

repo.Save((IContent) newBlock, SaveAction.Publish);

After that you will be able to add the block to the content area:

// add new block to the target block content area
writableTargetBlock.MyContentArea.Items.Add(new ContentAreaItem
{
    ContentLink = ((IContent) newBlock).ContentLink
});

repo.Save((IContent) writableTargetBlock, SaveAction.Publish);

EPiServer creates proxy objects for blocks in runtime and they implement IContent interface. When you need to use IContent member on a block, cast it to IContent explicitly.

When you create blocks using new operator, they are not saved in the database. Another problem is content area doesn't accept such objects, because they don't implement IContent intefrace (you need to get blocks from IContentRepository which creates proxies in runtime).

Blackout answered 18/1, 2015 at 18:5 Comment(4)
Thanks for the answer, It seems like it's working, but still have a problem, the line repo.Save(newBlock, SaveAction.Publish); marks an error saying that the best overload for Save has some invalid arguments, already tried repo.Save(newBlock, SaveAction.Publish,AccessLevel.Administer); and also IContentRepository.Save (repo,newBlock,saveAction.Publish)Sarcastic
Yep, looks like the same IContent cast issue. Try repo.Save((IContent) newBlock, SaveAction.Publish);Blackout
It works! now is showing the data as a block and editable properties are working fine. Just another question (I'm not sure if I shuld open another thread) the blocks are being added correctly, but when I go to the parent component, the ContentArea looks empty, so I checked and realized that the blocks are being added to the global assests folder, how can I "tell" the component to be shown into the content area in edit mode? I'm trying with this solution joelabrahamsson.com/custom-rendering-of-content-areas but isn't working for me so far. ThanksSarcastic
Yes, create another thread for your new question please, so others can find the question by topic and participate in answering. Write a bit more explanation of the problem or the code that is not working.Blackout

© 2022 - 2024 — McMap. All rights reserved.