Skip to content

Instantly share code, notes, and snippets.

@sniffdk
Last active February 28, 2022 10:03
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save sniffdk/7600822 to your computer and use it in GitHub Desktop.
Save sniffdk/7600822 to your computer and use it in GitHub Desktop.
Fake an UmbracoContext for use when doing published scheduling or other scenarios where UmbracoContext is normally null.
public class ContextHelpers
{
public static UmbracoContext EnsureUmbracoContext() {
if (UmbracoContext.Current != null)
{
return UmbracoContext.Current;
}
var httpContext = new HttpContextWrapper(HttpContext.Current ?? new HttpContext(new SimpleWorkerRequest("temp.aspx", "", new StringWriter())));
/* v7.3+ */
return UmbracoContext.EnsureContext(
httpContext,
ApplicationContext.Current,
new WebSecurity(httpContext, ApplicationContext.Current),
UmbracoConfig.For.UmbracoSettings(),
UrlProviderResolver.Current.Providers,
false);
/* v6.1.4 - v7.2.8 */
return UmbracoContext.EnsureContext(httpContext, ApplicationContext.Current, new WebSecurity(httpContext, ApplicationContext.Current), false);
/* v6.1.3 and earlier (I think) */
return (typeof(UmbracoContext)
.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
.First(x => x.GetParameters().Count() == 3)
.Invoke(null, new object[] { httpContext, ApplicationContext.Current, false })) as UmbracoContext;
}
}
public class EventHooks : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
base.ApplicationStarted(umbracoApplication, applicationContext);
Umbraco.Core.Services.ContentService.Published += (sender, args) =>
{
using (var umbracoContext = SiteHelpers.EnsureUmbracoContext())
{
var helper = new UmbracoHelper(umbracoContext);
foreach (var content in args.PublishedEntities)
{
var publishedContent = helper.TypedContent(content.Id);
var url = publishedContent.Url;
// do something with that url
...
}
}
};
}
}
@tajamal
Copy link

tajamal commented Jan 28, 2016

EnsureContext is deprecated, what do i instead? i am new to umbraco, can you help.

@sniffdk
Copy link
Author

sniffdk commented May 3, 2016

@tajamal sorry about the late answer, EnsureContext is not deprecated, just most of the overloads.

@jbreuer
Copy link

jbreuer commented Jun 24, 2016

I'm using this code to ensure the UmbracoContext.Current in the ApplicationStarting event. That way I can create an UmbracoHelper and use TypedContent because I need to fetch some nodes. Is this the best way to do this?

@alindgren
Copy link

@jbreuer, I think you can pass UmbracoHelper to the event handler. For example,

protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
  var helper = new UmbracoHelper(UmbracoContext.Current);
  ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"].GatheringNodeData 
        += (sender, e) =>   Indexer_GatheringNodeData(sender, e, helper);
}

I saw @JimBobSquarePants was getting UmbracoHelper as a param in the event handler in this article: http://24days.in/umbraco/2015/hacking-around-with-search-and-strong-typed-models/. And I saw how this was done in this article: http://staheri.com/my-blog/2015/march/custom-examine-indexing-using-umbraco-cache/.

This works for me (able to use TypedContent()) as follows:

private void Indexer_GatheringNodeData(object sender, IndexingNodeDataEventArgs e, UmbracoHelper helper)
{
  var node = helper.TypedContent(e.NodeId);
}

However, I was getting an exception when using Vorto (when calling GetVortoValue() on the IPublishedContent node). The technique in this gist seems to remedy that. Thanks @sniffdk and @Shazwazza!

@pgriffithsamaze
Copy link

pgriffithsamaze commented Nov 16, 2016

Hi Guys,

I'm really struggling with this to. Its all new so i haven't got a great understanding sorry.

I have a custom class where I am trying to use the UmbracoHelper.TypedContentAtRoot() to dynamically get the root node but the UmbracoContext.Current is always null and therefore it returns nothing. I have tried using the code above suggested by @YodasMyDad but it doesn't seem to work

if (UmbracoContext.Current == null) { var dummyHttpContext = new HttpContextWrapper(new HttpContext(new SimpleWorkerRequest("blah.aspx", "", new StringWriter()))); UmbracoContext.EnsureContext( dummyHttpContext, ApplicationContext.Current, new WebSecurity(dummyHttpContext, ApplicationContext.Current), UmbracoConfig.For.UmbracoSettings(), UrlProviderResolver.Current.Providers, false); }

If i use the following it seems to work. However, through my lack of understanding and resharpher warning me that EnsureContext is obsolete it concerns me of the potential impact.

var dummyContext = HttpContext.Current = new HttpContext(new HttpRequest(null, "https://www.google.com", null), new HttpResponse(null)); UmbracoContext.EnsureContext(new HttpContextWrapper(dummyContext), ApplicationContext.Current);

Reading here https://our.umbraco.org/forum/extending-umbraco-and-using-the-api/76889-background-process-value-cannot-be-nullparameter-name-httpcontext i can see that its a bug in 7.4.3. I am using 7.5.3 assembly: 1.0.6092.24019. I have also raised this in OUR https://our.umbraco.org/forum/extending-umbraco-and-using-the-api//81341-contentservice-not-creating-content. This will show you my code and what im trying to do. In short i am trying to do the following in a custom class

  1. Dynamically get the root node
  2. Get the first child where the document type == "reviewPage"
  3. Create child nodes of the reviewPage and setting values using the CreateContent & SaveAndPublishWithStatus.

Can some one please help?

Thanks
Paul

@bipin24x7
Copy link

Team, Do we have final confirmed new method which works with Umbraco 7.5.10? EnsureContext is deprecated. So, if we have any other option to generate UmbracoContext?

@sniffdk
Copy link
Author

sniffdk commented Mar 31, 2017

EnsureContext is not deprecated, not when looking at the source at least -> https://github.com/umbraco/Umbraco-CMS/blob/release-7.5.11/src/Umbraco.Web/UmbracoContext.cs#L113
If anyone needs help on this, come find us in the unofficial Slack channel -> umbracians.slack.com #help

@MichaelaIvanova
Copy link

Hi @Shazwazza,

Is is OK to have set up like this using Autofac:

 builder.Register(c => UmbracoContext.Current).InstancePerRequest();
 builder.Register(x => new UmbracoHelper(UmbracoContext.Current)).InstancePerRequest();

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment