Problem with dynamic block (image)

Vote:
 

<p>Hi!</p>

<p>I'm tearing my hair out over a block problem I've stumbled upon. I have a public form which creates new pages. These pages contain a contentarea where you can place images or slideshows (block). You can upload an image via the form and I would like to place the uploaded image inside the contentarea. Seemed like a rather easy thing to solve when I started out but I've found out it's not...&nbsp;</p> <p>The contentarea (Slideshow) can contain the blocktype SlideshowItem... SlideshowItem can contain an Image (contentreference). I've been thinking I could create some kind of local Slideshow block dynamically and then store the reference to the Image in that block. I wanna keep the contentarea and I don't wanna mess around with another kind of property (which I guess could solve my problem).&nbsp;I just can't figure this out... How would I go about doing this? I've been looking at&nbsp;http://joelabrahamsson.com/working-programmatically-with-local-blocks-in-episerver-7/ but it doesn't seem to work in my case. The page is not yet created so I can't create a local block for it programatically... I think!?</p>

<p>I kind of would like to do something like this (where ns holds the reference to the uploaded image):</p>

<p>newPage.Slideshow = contentRepository.Save(ns, SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);</p>

<p>Thankful for any ideas on how to go about this!</p> <p></p>

#113030
Nov 11, 2014 11:35
Vote:
 
<p>Hi,</p> <p>You could do something like this (untested code):</p> <pre class="brush:html;auto-links:false;toolbar:false" contenteditable="false">var repo = ServiceLocator.Current.GetInstance&lt;IContentRepository&gt;(); var assetHelper = ServiceLocator.Current.GetInstance&lt;ContentAssetHelper&gt;(); var newPage = repo.GetDefault&lt;YourPageType&gt;(ContentReference.StartPage); repo.Save(newPage, SaveAction.Save, AccessLevel.NoAccess); var assetFolder = assetHelper.GetOrCreateAssetFolder(newPage.ContentLink); var slideItem = repo.GetDefault&lt;SlideshowItem&gt;(assetFolder.ContentLink); repo.Save((IContent)slideItem, SaveAction.Publish, AccessLevel.NoAccess); newPage.Slideshow.Items.Add(new ContentAreaItem { ContentLink = ((IContent)slideItem).ContentLink }); repo.Save(newPage, SaveAction.Publish | SaveAction.ForceCurrentVersion, AccessLevel.NoAccess);</pre> <p></p> <p>This code will create a new instance of SlideshowItem, store it in the page's asset folder, then add it to the content area and finally publish the page.</p> <p></p> <p></p>
#113052
Nov 11, 2014 18:13
Vote:
 
<p></p> <p>Oh, and you need to add the image to the slideItem of course. You can't add the image reference directly to the content area. Unless you wanna skip the whole SlideshowItem block, and just add images directly to the content area.</p> <p></p>
#113053
Nov 11, 2014 18:16
Vote:
 
<p></p> <p>Btw, this has nothing to do with local blocks (aka blocks as properties). If you change the property type of the Slideshow property from ContentArea to SlideshowItem, then you would have a local block.</p> <p></p>
#113054
Nov 11, 2014 18:20
Vote:
 
<p>Thanks Johan! I follow and it seems like it should do it... Just tested it and ran into a white error page when posting the form but I should look into the whole thing a bit more when I have time. How would you go about adding the image straight to the contentarea (Slideshow - skipping the actual SlideshowItem block). Don't&nbsp;you have to assign the image to the slideItem property (slideItem.Image)? Feel a bit confused over the whole block thing in this case.</p>
#113066
Nov 12, 2014 10:21
Vote:
 
<p>You might have to remove "| SaveAction.ForceCurrentVersion" on the last row. ForceCurrentVersion only works if you already have a plublished version, I think...</p> <p></p> <p>You can add anything that implements IContent, i.e. has a ContentReference, to a content area. Out of the box you have pages, blocks, media and content folders.</p> <pre class="brush:html;auto-links:false;toolbar:false" contenteditable="false">newPage.Slideshow.Items.Add(new ContentAreaItem { ContentLink = yourImage.ContentLink }); // instead of newPage.Slideshow.Items.Add(new ContentAreaItem { ContentLink = ((IContent)slideItem).ContentLink }); </pre> <p></p> <p>In your case you might want to have more information on every slide in your slideshow, and not just the image? Then it makes sense to have a block with more properties, e.g. a link and text property.</p> <p></p>
#113068
Nov 12, 2014 10:29
Vote:
 
<p>Okey, that seems like a good and quite simple thing to do&nbsp;:) I still feel a bit confused about how I should reference the image (being uploaded with the form). Here's part of the code being used for&nbsp;handling the image being uploaded:</p> <pre class="brush:csharp;auto-links:false;toolbar:false;first-line:0" contenteditable="false">var file = Request.Files[0]; var contentRepository = ServiceLocator.Current.GetInstance&lt;IContentRepository&gt;(); var mediaObject = contentRepository.GetDefault&lt;ImageFileData&gt;(GetParent()); mediaObject.Name = DateTime.Now.ToString("yyyy-MM-dd_HHmm") + Path.GetExtension(file.FileName); mediaObject.Description = newPage.Name; var blob = ServiceLocator.Current.GetInstance&lt;BlobFactory&gt;().CreateBlob(mediaObject.BinaryDataContainer, Path.GetExtension(file.FileName)); blob.Write(file.InputStream); mediaObject.BinaryData = blob; newPage.TeaserImage = contentRepository.Save(mediaObject, SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);</pre> <pre class="brush:html;auto-links:false;toolbar:false" contenteditable="false">... repo.Save(newPage, EPiServer.DataAccess.SaveAction.Save, EPiServer.Security.AccessLevel.NoAccess);</pre> <p></p> <p>TeaserImage is a regular property for an image file and this part works like a charm. The new page is being created and the uploaded image is added to TeaserImage. I can't seem to get the reference "yourImage"/"theImage" part right (see below) in your suggestion. Been trying all kinds of different references (that kind of makes sense) to the file without any success. Ex:</p> <pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false"> var theImage = Locate.ContentRepository().Get&lt;IContent&gt;(newPage.TeaserImage) as ImageData; newPage.Slideshow.Items.Add(new ContentAreaItem { ContentLink = theImage.ContentLink });</pre> <p></p> <p></p> <p>The project builds but I still get a white internal error page when submitting the form. Any idea what I could be doing wrong?</p> <p></p>
#113083
Nov 12, 2014 16:30
Vote:
 
<p></p> <p>Your code looks fine. But you don't need to re-fetch the image if you already have the reference:</p> <pre class="brush:html;auto-links:false;toolbar:false" contenteditable="false">newPage.Slideshow.Items.Add(new ContentAreaItem { ContentLink = newPage.TeaserImage }); </pre> <p></p> <p>I think you need to debug to see where the code fails. Then you could post the stacktrace here.</p> <p></p>
#113087
Nov 12, 2014 18:17
Vote:
 
<p>Thanks but I've tried that as well... I get the same exception no matter which one I use. I've also tried to put it later in the code. The new page is then being saved at first but I get the same error/exception trying to save the page again:</p> <div class="line number1 index0 alt2"> <pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">var theImage = Locate.ContentRepository().Get&lt;IContent&gt;(newPage.TeaserImage) as ImageFileData; newPage.Slideshow.Items.Add(new ContentAreaItem { ContentLink = theImage.ContentLink }); repo.Save(newPage, EPiServer.DataAccess.SaveAction.Save, EPiServer.Security.AccessLevel.NoAccess);</pre> </div> <p>Looking at the event&nbsp;viewer&nbsp;I find this warning (telling me there's something wrong with the reference on the specific line):</p> <p>Exception information: <br /> Exception type: NullReferenceException <br /> Exception message: Object reference not set to an instance of an object.</p> <p>If I remove the&nbsp;part (trying to add the image to the contentarea) it works just fine. The contentarea accepts slidshow blocks and ImageFileData (a mediatype). A bit frustrating I must say :)</p> <p></p>
#113100
Nov 13, 2014 9:23
Vote:
 
<p></p> <p>Is there a reason why you can't debug the code? Looking in the event log is not the best method of finding exceptions in the code.</p> <p>If you're getting a null reference on theImage.ContentLink, it means that the image doesn't exist, or it isn't an ImageFileData.&nbsp;</p> <p></p>
#113138
Nov 13, 2014 19:46
Vote:
 
<p>Yes, kind of... I think. Every attemp trying to debug in VS&nbsp;I&nbsp;don't see any variables or their values. I'm in debug mode running the site but maybe I'm doing something wrong debugging? Shouldn't there be any output in VS while I'm surfing the site?</p>
#113335
Nov 18, 2014 16:35
* 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.