How to get document url from ContentService.Published?
I have created a .cs file (in App_Code) to watch for sending the url of published nodes to an external service.
I have come some of the way but don´t now the last part (see the "???").
I had hoped I could do it with content.Url, but that throws an error.
using System.Linq;
using Umbraco.Core;
using Umbraco.Web;
using Umbraco.Core.Composing;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
using System;
using System.Net;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
namespace OnDocEvents.Components
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class MyComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Components().Append<DocEvents>();
}
}
public class DocEvents : IComponent
{
private IUmbracoContextFactory _umbracoContext;
public void PublishedComponent(IUmbracoContextFactory umbracoContext)
{
_umbracoContext = umbracoContext;
}
public void Initialize()
{
ContentService.Published += ContentService_Published;
}
public void Terminate()
{
ContentService.Published -= ContentService_Published;
}
private void ContentService_Published(IContentService sender, ContentPublishedEventArgs e)
{
using (UmbracoContextReference contextReference = _umbracoContext.EnsureUmbracoContext())
{
UmbracoContext context = contextReference.UmbracoContext;
var content = context.Content.GetById(e.PublishedEntities.First().Id);
string url = ???;
}
}
}
}
What error are you receiving when trying to access the Url? I'm guessing your UmbracoContext is in an invalid state.
It's not a well documented topic but in order to guarantee a valid UmbracoContext outside of a Request scope you must wrap your IUmbracoFactory call in an IScopeProvider call to setup a valid scope.
I recently fell into a similar issue when handling an Examine Index event and found this answer
TLDR: try this:
using (_scopeProvider.CreateScope(autoComplete: true))
{
using (UmbracoContextReference contextReference = _umbracoContext.EnsureUmbracoContext())
{
UmbracoContext context = contextReference.UmbracoContext;
var content = context.Content.GetById(e.PublishedEntities.First().Id);
string url = content.Url;
}
}
I get the below error now and need to reference some namespace, but don´t now which.
Compiler Error Message: CS0103: The name '_scopeProvider' does not exist in the current context
Source Error:
Line 101: {
Line 102:
Line 103: using (_scopeProvider.CreateScope(autoComplete: true))
Line 104:{
Line 105: using (UmbracoContextReference contextReference = _umbracoContext.EnsureUmbracoContext())
You'll need to inject an IScopeProvider into the constructor of your class, along with an IUmbracoFactory. This is achieved using Dependency Injection. The docs are pretty good at explaining what's going on, read here.
I've taken the liberty of refactoring your code a little to get it working:
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Events;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
using Umbraco.Web;
namespace OnDocEvents.Components
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class MyComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Components().Append<DocEvents>();
}
}
public class DocEvents : IComponent
{
private readonly IUmbracoContextFactory _umbracoContext;
private readonly IScopeProvider _scopeProvider;
public DocEvents(IUmbracoContextFactory umbracoContext, IScopeProvider scopeProvider)
{
_umbracoContext = umbracoContext;
_scopeProvider = scopeProvider;
}
public void Initialize()
{
ContentService.Published += ContentService_Published;
}
public void Terminate()
{
ContentService.Published -= ContentService_Published;
}
private void ContentService_Published(IContentService sender, ContentPublishedEventArgs e)
{
var node = e.PublishedEntities.FirstOrDefault();
if(node == null)
{
return;
}
using (_scopeProvider.CreateScope(autoComplete: true))
{
using (var contextReference = _umbracoContext.EnsureUmbracoContext())
{
var context = contextReference.UmbracoContext;
var content = context.Content.GetById(node.Id);
var url = content.Url;
}
}
}
}
}
How to get document url from ContentService.Published?
I have created a .cs file (in App_Code) to watch for sending the url of published nodes to an external service.
I have come some of the way but don´t now the last part (see the "???").
I had hoped I could do it with content.Url, but that throws an error.
Hey Martin,
What error are you receiving when trying to access the Url? I'm guessing your
UmbracoContext
is in an invalid state.It's not a well documented topic but in order to guarantee a valid
UmbracoContext
outside of a Request scope you must wrap yourIUmbracoFactory
call in anIScopeProvider
call to setup a valid scope.I recently fell into a similar issue when handling an Examine Index event and found this answer
TLDR: try this:
Hi James,
Thanks. That sounds right. :)
I get the below error now and need to reference some namespace, but don´t now which.
Hi Martin,
You'll need to inject an
IScopeProvider
into the constructor of your class, along with anIUmbracoFactory
. This is achieved using Dependency Injection. The docs are pretty good at explaining what's going on, read here.I've taken the liberty of refactoring your code a little to get it working:
Cool! Thank you, James! :)
Your refactored code above works like a charm. :)
is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.