How to access currently published content in Umbraco

Getting up-to-date published content entry in Umbraco could be tricky. In this article, you will learn a technique to ensure you always access the current data from the published cache.

Introduction

Let's imagine a situation when you need to access and use published content right away a publication occurs in the Umbraco backoffice.

For an article, please assume we must send published content to any external API we are integrated with.

Probably, many developers will think that a custom ContentPublishedNotificationHandler of the Umbraco ContentService should be used for this purpose.

Please consider that for such a purpose, an appropriate design pattern with transaction should be used instead.

Otherwise, there is no guarantee that content will be sent, and data inconsistency between Umbraco and another system will occur sooner or later.

Sometimes, the content will be published in Umbraco but not sent to the external API.

Understanding the Challenge

If you expect that you can access published content right away after publishing a content node in the Umbraco or published content is already updated when the ContentPublishedNotification is fired, then you are unfortunately wrong.

Below, you can find a simple piece of code that shows how to access published content in the ContentPublishedNotification.

public class TestContentPublishedNotificationHandler
{
	public class TestContentPublishedNotificationHandlerComposer : IComposer
	{
		public void Compose(IUmbracoBuilder builder)
		{
			builder.AddNotificationHandler<ContentPublishedNotification, ContentPublishedNotificationHandler>();
		}
	}

	public class ContentPublishedNotificationHandler : INotificationHandler<ContentPublishedNotification>
	{
		private readonly IUmbracoContextFactory _umbracoContextFactory;

		public ContentPublishedNotificationHandler(IUmbracoContextFactory umbracoContextFactory)
		{
			_umbracoContextFactory = umbracoContextFactory;
		}

		public void Handle(ContentPublishedNotification notification)
		{
			var content = notification.PublishedEntities.First();

			using (var ctxRef = _umbracoContextFactory.EnsureUmbracoContext())
			{
				var publishedContent = ctxRef.UmbracoContext.Content.GetById(content.Id);				
			}
		}
	}
}

Common IPublishedContent Misconceptions and Pitfalls

Unfortunately, I have been aware since the beginning of Umbraco that such code will not work each time as expected.

First, we must be aware that the IPublishedContent object could be null if the content is published the first time.

Secondly, in case we are publishing the same content again and updating it, we need to be aware that published content can contain properties that are not updated.

This is caused by the publishing process's design and Umbraco's refreshing mechanism.

I thought that maybe it was solved in the latest version of the system, but I found a quite fresh issue and explanation in this thread: https://github.com/umbraco/Umbraco-CMS/issues/13339

The funny thing is that I tried so hard to replicate the issue at localhost, but it never occurred, even when I created thousands of nodes.

However, I understand that everything is much faster on localhost than on other environments.

Effective Strategy for Accessing Published Content

Of course, we can check if any property is not updated, but there is a special built-in property on which we can rely.

Please check the tricky code below, which could be used for any custom solution when you would like to access published content in case of publishing.

As you can see, you can easily ensure that the published content cache is current.

If published content has not been updated yet, you must retry it until the dates are equal.

Therefore, the code below is a universal piece that could be used in any scenario.

//Id of the content which has been just published
int nodeId = 1234;

using (var ctxRef = _umbracoContextFactory.EnsureUmbracoContext())
{
    var publishedContent = ctxRef.UmbracoContext.Content.GetById(nodeId);

    if (publishedContent != null)
    {
        var content = _contentService.GetById(nodeId);

        content = _contentService.GetVersion(content.PublishedVersionId);

        if (publishedContent.UpdateDate.Equals(content.PublishDate))
        {
            //TODO: You can use up to date published content
        }
    }
}

As you can see, we need to check if the published content exists.

Then, we need to obtain a published version of the content by ContentService.

Finally, we can compare crucial dates to ensure we access the correct data.

Conclusion

Accessing published content in Umbraco properly requires more than basic knowledge.

This article has provided solution for common published content pitfalls and embraces best practices for real-time content handling. 

This may be critical when dealing with complex integrations and headless approaches. 

By implementing this technique, you ensure data integrity and system reliability.

🌐 Explore More: Interested in learning about Umbraco and web development insights?

Explore our blog for a wealth of information and expert advice.

↑ Top ↑