Programmatically created non-editable page


I need to instantiate a page programmatically, where the editor cannot move it or change the url. Basically I need a specific url pattern and a custom instance.


How would I go about that?



May 09, 2014 9:48

Sounds like you need to hook up to MovingPage and SavingPage events and cancel out or reset UrlSegment if it's "dirty".

An example post for EPi6 

Edited, May 09, 2014 11:41

That or just not give Editors access to the page.

May 09, 2014 11:45

Petter, most probably editors would need to change other properties, that's just a guess. So as Johan said - I would hook on events and inspect that page's data during its lifecycle and prevent some of actions.

May 09, 2014 11:56

Yes that is why I was poiting to Johans solution too. But from the topic and the fact that it wasn't specified, I thought I would advice to try with no editor access as well..

May 09, 2014 12:09

You can use an editor descriptor to hide or make a property ready only. Use this in combination with specific a model type or an attribute to control this:


using System;
using System.Collections.Generic;
using EPiServer.Core;
using EPiServer.Shell.ObjectEditing;
using EPiServer.Shell.ObjectEditing.EditorDescriptors;

namespace Samples
[EditorDescriptorRegistrationAttribute(TargetType = typeof(ContentData))]
public class SiteMetadataExtender : EditorDescriptor
public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
foreach (ExtendedMetadata property in metadata.Properties)
if (property.PropertyName == "iroutable_routesegment" && true)//Whatever logic you want to control this by, perhaps an attribute on the model class or the type of the model class)
//either this:
//property.ShowForEdit = false;
// to hide the URL or
property.EditorConfiguration["readOnly"] = true;
//to make it read only.

May 09, 2014 12:59

Nice, so final solution would be to prevent editing URLSegment by UIDescriptor and preventing moving around page tree by hooking to events?

May 09, 2014 13:12

I didn't know of the readOnly setting. Thanks Linus!

May 09, 2014 13:20

@Johan: I must admit that I had to browse the source code to see how it was done ;)

May 09, 2014 13:23

@Valdis: Yes, that sounds reasonable. Perhaps an attribute on the model class that could be used to control both of these limitations...

May 09, 2014 13:39

Clever... Combined with this code in a startup Sequence its perfekt :-)



public void CheckLoginControllerExists(object sender, EventArgs eventArgs)
var serviceLocationHelper = ServiceLocator.Current.GetInstance<ServiceLocationHelper>();
var pageTypeRepository = ServiceLocator.Current.GetInstance<PageTypeRepository>();
var repository = ServiceLocator.Current.GetInstance<IContentRepository>();
var siteDefinitionRepository = ServiceLocator.Current.GetInstance<SiteDefinitionRepository>();
var site = siteDefinitionRepository.Get("SiteName");
if (site == null) //site is not defined, bail out...

var defaultStartPage = repository.Get<PageData>(site.StartPage);

var criterias = new PropertyCriteriaCollection //set a search criteria
// Find pages of a specific page type
new PropertyCriteria()
Name = "PageTypeID",
Condition = CompareCondition.Equal,
Required = true,
Type = PropertyDataType.PageType,
Value = pageTypeRepository.Load(typeof(LoginPage)).ID+"" //find the id of the type of page

PageDataCollection newsPageItems = serviceLocationHelper.PageCriteriaQueryService().FindPagesWithCriteria(defaultStartPage.PageLink, criterias);

foreach (var pageData in newsPageItems)
var o = pageData as LoginPage;
if (o != null) //we found our login page
//is it a child of startpage?

if (o.ParentLink == defaultStartPage.ContentLink && o.Name == "login")
return; // we found the page, everything is ok.. move along

//there is no login page, make one
var loginPage = repository.GetDefault<LoginPage>(defaultStartPage.ContentLink, pageTypeRepository.Load(typeof(LoginPage)).ID);
loginPage.Name = "login";
loginPage.URLSegment = UrlSegment.CreateUrlSegment(loginPage);
repository.Save(loginPage, EPiServer.DataAccess.SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);

May 09, 2014 15:01
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.