Vulnerability in EPiServer.Forms

Try our conversational search powered by Generative AI!

Stefan Forsberg
May 7, 2010
(1 votes)

How do you setup different states that depends on EpiServer page structure?

Let’s say you have a page that acts as a container for news. The page simply lists all it’s children in a PageList. Now our GUI developer want us to have at least 21 pages to that they can check that the html they wrote for the paging functionality behaves ok. Soon after you need to verify that if the container doesn’t contain any children at all a message is displayed to inform the user that no news were found.

While these examples might seem somewhat silly the thing I’m getting at is that sometimes you (or your team) need your page structure to be in a certain state for you to verify and or test something.



So, what options do we have today to accomplish this?


1. The manual approach

This is basically just going into edit mode and create whatever structure(s) you need to verify your testing.


2. Creating lists programmatically

In the above examples we don’t really care what data is in the news items them self so we can create lists specifically for the test scenarios . Since we’re using a PageList we do have to make sure that we’re using a PageDataCollection and that the pages are correctly setup to not be filtered by FilterForVisitor.


3. Hooking up to DataFactory.LoadedChildren

This event enables us to change the resulting PageDataCollection. This results in much the same approach as number 2 above but keep in mind that this will also affect the way that the Episerver tree itself is generated too.


4. Using a custom page type builder.

This enables us to create a whole structure that behaves exactly like ordinary pages without them actually existing.


So how do these techniques measure up?

My problem with 1-3 is that modifying your “production” code and setup the state for your tests there almost always leads to a mess. You get those if debug statements (or even worse, code you have to remember to uncomment before deploying) and all in all it just feels fragile. Alternative 1 also can be tricky to do in a unit testing scenario since it can require manual fixing, which probably means that those test won’t run / pass very often.

Alternative 4 can be a good solution but it has some drawbacks. Depending on how much and what you want to test it might be slightly overkill to implement. A custom page provider also requires a enterprise license, which probably isn’t a problem in your local development but if you for some reason would like to use your faked structure on the live server (yes I know this is highly unlikely) you might not be able to do so. The final drawback is somewhat of a nitpick for me, but to use this in your unit tests you have to setup the whole configuration for episerver in your tests. Sure, it doesn’t take a trip to the database, but still.


Using DI and PTB 1.2

One of the new features in PageTypeBuilder 1.2 is the ability to inject dependencies into your TypedPageData classes. Joel has written a post about this here. I’ve done some simple proof on concepting about using this to setup structure, so please take the code for what it is.

To be able to controll the fetching of child pages we inject a dependency to IPageSource. Using the example above out news container could look like this

   1: [PageType("345D0610AE114BC5B5AAE8450D364757", Name = "News Container", Filename = "~/UI/Pages/NewsContainer.aspx")]
   2: public class NewsContainer : TypedPageData
   3: {
   4:     private readonly IPageSource pageSource;
   6:     public NewsContainer(IPageSource pageSource)
   7:     {
   8:         this.pageSource = pageSource;
   9:     }
  11:     public List<NewsItem> GetNews()
  12:     {
  13:         return pageSource
  14:             .GetChildren(PageLink)
  15:             .OfType<NewsItem>()
  16:             .ToList();
  17:     }
  18: }


We can now create “fake” classes to use for when we actually have the need to see the pages (for instance the scenario with paging described in the beginning of the post).

   1: public class FakeData : IPageSource
   2: {
   3:     public PageDataCollection GetChildren(PageReference pageLink)
   4:     {
   5:         var pageTypeID = PageTypeResolver.Instance.GetPageTypeID(typeof (NewsItem)).Value;
   6:         var pageType = PageType.Load(pageTypeID);
   8:         InitializeBaseData initializer = new InitializeBaseData();
  10:         PageDataCollection pageDataCollection = new PageDataCollection();
  11:         for (int i = 0; i < 50; i++)
  12:         {
  13:             var newsItem = new NewsItem { MainBody = "Hello" };
  14:             initializer.InitializePageData(newsItem, "SomePageName" + i, pageType, Guid.NewGuid(), new PageReference(5000 + i), pageLink, new List<string>(), string.Empty);
  15:             pageDataCollection.Add(newsItem);
  16:         }
  18:         return pageDataCollection;
  19:     }
  21:     public PageData GetPage(PageReference pageLink)
  22:     {
  23:         throw new NotImplementedException();
  24:     }
  27:     public PageData CurrentPage
  28:     {
  29:         get { throw new NotImplementedException(); }
  30:     }
  31: }


The class InitializeBaseData is more a less a copy of the reflected code from the method InitializePageData in PageProviderBase (minus the UrlSegment part since it’s method GetUrlFriendlySegment for some reason is internal). The reason for doing this is to make sure the PageData part of the TypedPageData has values to be able to use it with the PageList controll.



In our unit tests we can simply mock the IPageSource interface to test whatever scenario we want to test.

   1: [TestMethod]
   2: public void Some_pretty_redundant_test_that_doesnt_really_test_anything()
   3: {
   5:     var pageSourceMock = new Moq.Mock<IPageSource>();
   6:     pageSourceMock.Setup(x => x.GetChildren(It.IsAny<PageReference>())).Returns(new PageDataCollection());
   7:     NewsContainer container = new NewsContainer(pageSourceMock.Object);
   9:     Assert.IsTrue(container.GetNews().Count == 0);
  10: }


Hopefully I’ll have time to come back to this subject in a later post.


May 07, 2010


Joel Abrahamsson
Joel Abrahamsson Sep 21, 2010 10:33 AM

Great post Stefan!

I would love to see a follow up where you combine this with StructureMap profiles creating a lifecycle aware site.

Please login to comment.
Latest blogs
Join the Work Smarter Webinar: Working with the Power of Configured Commerce (B2B) Customer Segmentation December 7th

Join this webinar and learn about customer segmentation – how to best utilize it, how to use personalization to differentiate segmentation and how...

Karen McDougall | Dec 1, 2023

Getting Started with Optimizely SaaS Core and Next.js Integration: Creating Content Pages

The blog post discusses the creation of additional page types with Next.js and Optimizely SaaS Core. It provides a step-by-step guide on how to...

Francisco Quintanilla | Dec 1, 2023 | Syndicated blog

Stop Managing Humans in Your CMS

Too many times, a content management system becomes a people management system. Meaning, an organization uses the CMS to manage all the information...

Deane Barker | Nov 30, 2023

A day in the life of an Optimizely Developer - Optimizely CMS 12: The advantages and considerations when exploring an upgrade

GRAHAM CARR - LEAD .NET DEVELOPER, 28 Nov 2023 In 2022, Optimizely released CMS 12 as part of its ongoing evolution of the platform to help provide...

Graham Carr | Nov 28, 2023

A day in the life of an Optimizely Developer - OptiUKNorth Meetup January 2024

It's time for another UK North Optimizely meet up! After the success of the last one, Ibrar Hussain (26) and Paul Gruffydd (Kin + Carta) will be...

Graham Carr | Nov 28, 2023

Publish content to Optimizely CMS using a custom GPT from OpenAI 🤖

Do you find the traditional editor interface complicated and cluttered? Would you like an editorial AI assistant you can chat with? You can!

Tomas Hensrud Gulla | Nov 28, 2023 | Syndicated blog