Access Content Cache from Hangfire in v10 & 11? What's going on?
I'm working on migrating our v8 site to v11. (I just upgraded it from v10 to v11.) We have Hangfire tasks that need to access IPublishedContent. Previously we injected IUmbracoContextFactory and used _umbracoContext.EnsureUmbracoContext() to get an UmbracoContextReference, and we were able to get to the cache from there.
In Umbraco 10 and 11, when I use EnsureUmbracoContext() in the context of a Hangfire task, I get System.NullReferenceException: 'Object reference not set to an instance of an object.'
EnsureUmbracoContext() should ENSURE UmbracoContext, shouldn't it?
I saw some suggestions to wrap the code in a call to _scopeProvider.CreateScope(), but I get a System.NullReferenceException: 'Object reference not set to an instance of an object.' on CreateScope() as well.
What's the proper way to access the content cache outside of an HTTP request in v10 & v11? I don't want to hack around it by making an HTTP call to an API controller. There seems to be a lot of confusion on this, but this is rather important. Am I just running into bugs? I got the same behavior in v10 and v11.
I realized I should do a minimum code example, and EnsureUmbracoContext() worked correctly when I did that. I've narrowed down the issue to some sort of dependency injection weirdness; it wasn't injecting the dependencies on my class because it couldn't find one of them (and was failing silently because I had an empty constructor available). Once I removed the other dependencies and constructors, it worked fine.
So if you have this same issue, try injecting ONLY IUmbracoContextFactory, and make sure you only have one constructor. If that still doesn't work, try it in a separate minimum class, something like the one below.
using Umbraco.Cms.Core.Web;
namespace MyProject.Classes
{
public class HangfireTest
{
private readonly IUmbracoContextFactory _umbracoContextFactory;
public HangfireTest(IUmbracoContextFactory umbracoContextFactory)
{
_umbracoContextFactory = umbracoContextFactory;
}
public void Run()
{
var cref = _umbracoContextFactory.EnsureUmbracoContext();
using (var ctx = cref.UmbracoContext)
{
var contentCache = ctx.Content;
if (contentCache != null)
{
var root = contentCache.GetAtRoot();
var asdfasdf = root.FirstOrDefault();
var homepage = contentCache.GetById(1234);
}
}
}
}
}
Access Content Cache from Hangfire in v10 & 11? What's going on?
I'm working on migrating our v8 site to v11. (I just upgraded it from v10 to v11.) We have Hangfire tasks that need to access
IPublishedContent
. Previously we injectedIUmbracoContextFactory
and used_umbracoContext.EnsureUmbracoContext()
to get anUmbracoContextReference
, and we were able to get to the cache from there.In Umbraco 10 and 11, when I use
EnsureUmbracoContext()
in the context of a Hangfire task, I getSystem.NullReferenceException: 'Object reference not set to an instance of an object.'
EnsureUmbracoContext() should ENSURE UmbracoContext, shouldn't it?
I saw some suggestions to wrap the code in a call to
_scopeProvider.CreateScope()
, but I get aSystem.NullReferenceException: 'Object reference not set to an instance of an object.'
onCreateScope()
as well.What's the proper way to access the content cache outside of an HTTP request in v10 & v11? I don't want to hack around it by making an HTTP call to an API controller. There seems to be a lot of confusion on this, but this is rather important. Am I just running into bugs? I got the same behavior in v10 and v11.
Thanks.
I realized I should do a minimum code example, and EnsureUmbracoContext() worked correctly when I did that. I've narrowed down the issue to some sort of dependency injection weirdness; it wasn't injecting the dependencies on my class because it couldn't find one of them (and was failing silently because I had an empty constructor available). Once I removed the other dependencies and constructors, it worked fine.
So if you have this same issue, try injecting ONLY IUmbracoContextFactory, and make sure you only have one constructor. If that still doesn't work, try it in a separate minimum class, something like the one below.
is working on a reply...