This content is archived. See latest version here

Last updated: Mar 25 2013

Table of Contents


Through IContentRepository it is possible to save and load IContent instances. The most typical content instance is types inheriting PageData, although it is possible to load and save other content types than pages. These content instances will not show up in the page tree in edit mode.

One use case could be for example when implementing comment functionality. In that case each comment could be saved as an IContent under the page that is commented on. However, the comments will not be seen in page tree.

Below is an example on how such a Comment type could be defined and persisted.

Defining Comment Content Type

The following code shows the Comment class:

public class CommentUser : BlockData
    public virtual string Email { get; set; }
    public virtual string UserName { get; set; }

public class Comment : IContent
    public virtual CommentUser User { get; set; }
    public virtual string Body { get; set; }

    #region IContent
    private PropertyDataCollection _properties = new PropertyDataCollection();

    public string Name { get; set; }
    public ContentReference ContentLink { get; set; }
    public ContentReference ParentLink { get; set; }
    public Guid ContentGuid { get; set; }
    public int ContentTypeID { get; set; }
    public bool IsDeleted { get; set; }
    public PropertyDataCollection Property
        get { return _properties; }
    public bool IsNull
        get { return _properties.Count == 0; }

Registering ContentType

Each IContent that is stored in the CMS content database must have a corresponding ContentType registered. Classes inheriting from PageData or BlockData will be automatically scanned for and registered during initialization. For other content types the registration has to be done explicitly.
The class SingleModelRegister can be used to register a single type. It works in the same way as the scanning for pages or blocks meaning it will check if the type exists, and if so update it according to code changes and if it does not exist it will create the type. It will also take care of registering it with a proxy if properties are virtual and compiler generated. The register method should be called each time during initailization even if the type already exist in the database.

The registration for Comment is done as shown in the following example:

public class InitializationModule : IInitializableModule
    public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context)
        var register = context.Locate.Advanced.GetInstance<SingleModelRegister<Comment>>();

    public void Preload(string[] parameters){}
    public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context){}

Saving and Loading Comment

The instance of the interface IContentRepository can be used to create, load and save content instances. The below code shows how to create a Comment instance, save it and load it back.

public class CommentHandler
    private IContentRepository _contentRepository;
    public CommentHandler(IContentRepository contentRepository)
        _contentRepository = contentRepository;

    public Comment CreateAComment()
        var comment = _contentRepository.GetDefault<Comment>(PageReference.RootPage, LanguageSelector.AutoDetect());
        comment.Name = "acomment";
        comment.User.Email = "";
        comment.Body = "This is a comment";

        var contentLink = _contentRepository.Save(comment, EPiServer.DataAccess.SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);
        var loadedComment = _contentRepository.Get<Comment>(contentLink);

        System.Diagnostics.Debug.Assert(comment.User.Email == loadedComment.User.Email);
        System.Diagnostics.Debug.Assert(comment.Body == loadedComment.Body);

        return comment;

See Also

The above example showed how to register, load and save custom IContent instances. See for example Partial Routing for a description on how routing can be extended for custom content instances and how they could be coupled with a renderer.

In the Relate template package there is an IContent implementations for blogs and blog entries.

Do you have feedback on this documentation? Send an email to For development-related questions and discussions, refer to our Forums on