Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Tyler Brown 62 posts 209 karma points
    Aug 21, 2013 @ 22:30
    Tyler Brown
    0

    Published EventHandler not populating url?

    Using Umbraco 6.1.3. I am trying to use the Published EventHandler to update an external file based on the content published.  I am able grab property values from the content and write to this external file, but I need to get the url of the published page as well.  To do this, I am using:

     

    private void UpdateTableFileEventHandler(Umbraco.Core.Publishing.IPublishingStrategy sender, Umbraco.Core.Events.PublishEventArgs e)
    {
    foreach (var item in e.PublishedEntities)
    {
    UmbracoHelper UMHelper = new UmbracoHelper(UmbracoContext.Current);
    IPublishedContent publishedContent = UMHelper.TypedContent(item.Id);
    }
    }

    This works, as long as the document has been published before, but if it is a new document, apparently it isn't in the cache yet because I get a null reference. Anyone know how to grab the url of a newly published item? I only see 'Publishing' and 'Published' as options and I've tried both. What am I doing wrong?

  • Tyler Brown 62 posts 209 karma points
    Aug 22, 2013 @ 16:57
    Tyler Brown
    0

    The same thing happens when using  Umbraco.Core.Services.ContentService.Published.  I cannot get the url of a piece of content that has just been published if it wasn't previously in the cache prior to publishing. Do I need to refresh the umbraco cache? Is there a non-deprecated method to refresh the cache?

  • Mads Krohn 211 posts 504 karma points c-trib
    Aug 22, 2013 @ 22:38
    Mads Krohn
    0

    Hi Tyler
    Just to make sure I understand your problem, did you try to get a url like this:

    var url = new UmbracoHelper(UmbracoContext.Current).NiceUrl(item.Id);
    

    Or how did you try to get to the url?

    Cheers
    - Mads

  • Tyler Brown 62 posts 209 karma points
    Aug 23, 2013 @ 04:01
    Tyler Brown
    0

    I'm using:


    UmbracoHelper UMHelper = new UmbracoHelper(UmbracoContext.Current);
    IPublishedContent publishedContent = UMHelper.TypedContent(item.Id);
    string strUrl = publishedContent.Url;

    And this works unless the item was not previously in the umbraco cache.  So it seems like it is behaving as if the cache hasn't refreshed yet to reflect the published content.

    Thanks!

    Tyler

  • Mads Krohn 211 posts 504 karma points c-trib
    Aug 23, 2013 @ 22:47
    Mads Krohn
    0

    Hi Tyler
    Did you get any progress on this one? Just checking before I commit any more time to it :P
    Cheers

  • Tyler Brown 62 posts 209 karma points
    Aug 24, 2013 @ 03:50
    Tyler Brown
    0

    Hi Mads,

    Unfortunately, no... there has to be a way to get the url of newly published content, right? just haven't found it yet :)

  • Mads Krohn 211 posts 504 karma points c-trib
    Aug 24, 2013 @ 08:52
    Mads Krohn
    0

    Hi Tyler
    Did you try to use the NiceUrl method I posted, I'm curious to hear if that could solve the issue.

  • Tyler Brown 62 posts 209 karma points
    Aug 24, 2013 @ 14:43
    Tyler Brown
    0

    I tried NiceUrl and it gives me a '#' for the url the first time the content is published.  Once it is published in the cache, if I publish again, the url is correct. So it lookes like the same issue. For some reason the cache isn't updated when my method fires (I think?).

     

    Tyler

  • Mads Krohn 211 posts 504 karma points c-trib
    Aug 24, 2013 @ 21:58
    Mads Krohn
    0

    Hi Tyler

    I just did a test on an almost-vanilla 6.1.3 and I'm not seeing the issue you've described.
    Using the code below, I get the correct url every time on first publish of a newly created node.

    ContentService.Published += (sender, args) =>
    {
        foreach (var content in args.PublishedEntities)
        {
            var helper = new UmbracoHelper(UmbracoContext.Current);
            var publishedContent = helper.TypedContent(content.Id);
            var strUrl = publishedContent.Url;
        }
    };
    

    Just a quick thought, are publishing through scheduled publishing?

    Cheers
    - Mads

  • Tyler Brown 62 posts 209 karma points
    Aug 25, 2013 @ 04:23
    Tyler Brown
    0

    Mads,

    using Umbraco.Core.Services.ContentService.Published I still get a null reference the first time the page is published.  Below is how I implemented the code you sent:

        public class SearchTable : ApplicationEventHandler
    {
    public SearchTable()
    {
    Umbraco.Core.Services.ContentService.Published += (sender, args) =>
    {
    foreach (var content in args.PublishedEntities)
    {
    var helper = new UmbracoHelper(UmbracoContext.Current);
    var publishedContent = helper.TypedContent(content.Id);

    var strUrl = publishedContent.Url;
    HttpContext.Current.Response.Write("url: " + strUrl);
    }

    };

    }
    }

    My original code looked like this:

     public class SearchTable : ApplicationEventHandler
    {
    public SearchTable()
    {

    Umbraco.Core.Publishing.PublishingStrategy.Published += UpdateTableFileEventHandler;

    }


    private void UpdateTableFileEventHandler(Umbraco.Core.Publishing.IPublishingStrategy sender, Umbraco.Core.Events.PublishEventArgs<Umbraco.Core.Models.IContent> e)
    {
    foreach(var item in e.PublishedEntities)
    {
    UmbracoHelperUMHelper=newUmbracoHelper(UmbracoContext.Current);
    IPublishedContent publishedContent =UMHelper.TypedContent(item.Id);
    string strUrl = publishedContent.Url;

    }
    }

     

    So Before I was using Umbraco.Core.Publishing.PublishingStrategy.

     

    Tyler

  • Mads Krohn 211 posts 504 karma points c-trib
    Aug 25, 2013 @ 10:02
    Mads Krohn
    101

    Hi Tyler

    I'm curious as to how that code even works :)
    I believe the right way to hook your evens is in the ApplicationStarted method on the ApplicationEventHandler.
    Could you try the code in this gist?

  • Tyler Brown 62 posts 209 karma points
    Aug 26, 2013 @ 01:06
    Tyler Brown
    0

    Mads,

    I did a quick test with the code you submitted on Git and it works perfectly.  It also makes much more sense to me! Thanks!

    As for my original code working, Visual Studio didn't complain, so I went with it! :)

    Actually, I thought the way I was doing it was the correct way for Umbraco 6, but reading the description of Umbraco.Core.Publishing.PublishingStrategy, it says it is 'currently an interconnection between the new public api and legacy api for publishing.' So I was wondering if this is in place for compatibility with version 4... either way, it is firing too soon for the umbraco cache to reflect publishing changes.

     

    Tyler

  • Mads Krohn 211 posts 504 karma points c-trib
    Aug 26, 2013 @ 02:14
    Mads Krohn
    0

    Hi Tyler

    That's awesome! :)

    One thing you do have to be careful about though is this line:

    var helper = new UmbracoHelper(UmbracoContext.Current);
    

    The problem is, that if you are doing delayed publishing, by setting a publish date, the UmbracoContext.Current will be null at publish time, which will cause stuff to fail. Unfortunately, AFAIK, everything involving creating a new UmbracoContext is internal at the moment, so your only option to work around this, I think, is through reflection which is pretty nasty.

    I would love for the Core team to get a solution in place for this, but hopefully for the time being, it won't affect you too much.

    Cheers
    - Mads

  • Tyler Brown 62 posts 209 karma points
    Aug 26, 2013 @ 14:30
    Tyler Brown
    0

    Thanks for the heads-up.  Definitely something to keep in mind!

    Tyler

  • Bilal Isa 60 posts 76 karma points
    Nov 22, 2013 @ 14:56
    Bilal Isa
    0

    Hello,

    Thanks for the post which has been very helpful to me. I have a client that's doing dalayed publishing and I need a nice url for the node I'm publishing so I can add it to a table and send notices to members. Is there any way around UmbracoContext.Current being null at publish time?

    Thanks in advance.

    /Bilal

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 22, 2013 @ 15:02
    Mads Krohn
    0

    Hey Bilal

    Firstly, which Umbraco version are you using?

    Cheers - Mads

  • Bilal Isa 60 posts 76 karma points
    Nov 22, 2013 @ 15:09
    Bilal Isa
    0

    Hey Mads,

    I'm using version 6.1.6.

    /Bilal

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 22, 2013 @ 15:41
    Mads Krohn
    0

    Hi Bilal

    Great, that makes everything it a lot easier since the internal methods for creating an UmbracoContext have been made public. What I normally do is wrap everything in saved/published/etc events in a using statement like this (gist). This way, I'm making sure that the HttpContext and UmbracoContext are never null.

    Let me know if it works for you.

    Cheers
    - Mads

  • Bilal Isa 60 posts 76 karma points
    Nov 22, 2013 @ 16:13
    Bilal Isa
    0

    Hi Mads,

    It worked like magic. Thank you.

    /Bilal

     

  • Bilal Isa 60 posts 76 karma points
    Nov 24, 2013 @ 23:58
    Bilal Isa
    0

    Hi again Mads

    Do you have some suggestions to how you could extend the solution to the case you have a multi site setup with more than one hostname?

    /Bilal

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 25, 2013 @ 00:21
    Mads Krohn
    0

    Hi Bilal

    I updated my gist. There might be a better way around the API, but the idea here is basically to get all domains for the given published item and then just generate url's from that and the item's url that we also got. Hope it makes sense. I haven't tested the code, but it compiles and *should* work :)

    Cheers
    - Mads

  • Bilal Isa 60 posts 76 karma points
    Nov 25, 2013 @ 01:20
    Bilal Isa
    0

    Hello Mads

    This code vardomains=Domain.GetDomainsById(content.Id); is returning an empty array. I checked umbracoDomains and it's empty although I have

    hostnames on my language nodes. So maybe umbraco 6.1.6 is storing them somewhere else. What I did was replace you hardcoded url in HttpContextEnsurer's constructor

    with the hostname for the Danish site and then I could get the url for items with delayed publishing. But what if you have a multisite in one umbraco instance?

     

     

     

     

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 25, 2013 @ 01:33
    Mads Krohn
    0

    Ok, another gist update.

    Seems that you need the actual root node where the domains are declared. You could get it by traversing the content item ancestors, as I did in the gist now. Just replace "LanguageNode" with whatever your document type is called.

    Any luck with that?

  • Bilal Isa 60 posts 76 karma points
    Nov 25, 2013 @ 09:22
    Bilal Isa
    0

    Hi Mads

    Thanks for your feedback. I did something like this:

    public static class ContextHelper
        {
            public static IDisposable EnsureHttpContext(int contentId)
            {
                return new HttpContextEnsurer(contentId);
            }
    
            class HttpContextEnsurer : IDisposable
            {
                private readonly bool _fake;
                public HttpContextEnsurer(int contentId)
                {
                    _fake = HttpContext.Current == null;
                    if (_fake)
                    {
                        var domainItem = ApplicationContext.Current.Services.ContentService.GetAncestors(contentId).FirstOrDefault(x => x.ContentType.Alias == "Homepage");
                        if (domainItem != null)
                        {
                            var domains = umbraco.cms.businesslogic.web.Domain.GetDomainsById(domainItem.Id);
    
                            HttpContext.Current = new HttpContext(new HttpRequest("", string.Format("{0}://{1}", Uri.UriSchemeHttp, domains[0].Name), ""), new HttpResponse(new StringWriter()));
                        }
                    }
                    if (UmbracoContext.Current == null)
                    {
                        UmbracoContext.EnsureContext(new HttpContextWrapper(HttpContext.Current), ApplicationContext.Current, true);
                    }
                }
    
                public void Dispose()
                {
                    if (_fake)
                    {
                        HttpContext.Current = null;
                    }
                }
            }
        }
    
  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 25, 2013 @ 10:50
    Mads Krohn
    0

    Hi Bilal

    That's not exactly what I meant :)
    Any particular reason you decided to implement it like that? Did it work out for you? If yes, then that's just great :)

    Cheers

  • Bilal Isa 60 posts 76 karma points
    Nov 25, 2013 @ 12:00
    Bilal Isa
    0

    Hi Mads,

    The reason I implemented it in that way is that I need to know the domain / hostname for the node before I try to ensure I have a Umbraco Context object and I need to substitute it in place of "http://tempuri.org" for it work. I'm I missing something?

    And yes, it worked for me. But I need to do look into if it's an optimal solution.

    /Bilal

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 25, 2013 @ 16:10
    Mads Krohn
    0

    Hi Bilal

    Why do you need to know the domain / hostname for the node before trying to ensure that you have an UmbracoContext?

    As I see it, you need the relative url of your content item and then you need to concatenate it with the different domains from your root content item. Did you try and follow my gist? Did it cause you trouble?

    Cheers

  • Bilal Isa 60 posts 76 karma points
    Nov 25, 2013 @ 22:47
    Bilal Isa
    0

    Hello Mads,

    I must have misunderstood you. Anyway I tried your solution and it looks like it works.

    However in some cases I experience that helper.TypedContent(content.Id) returns null on publishing and delayed publishing which doesn't really make sense.

    Also I found out that I didn't need find the domain because varstrUrl=publishedContent.Url was already given med the full url.

    /Bilal

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 25, 2013 @ 22:56
    Mads Krohn
    0

    Yes, you probably see this whenever you publish a content item for the first time, and the item is not yet in the xml cache. See my comments on this issue.

    And yes, var strUrl = publishedContent.Url will give you a full url, the domains are only necessary if you need url's for multiple domains at the same time, which is what I thought you wanted :)

    Cheers

  • Bilal Isa 60 posts 76 karma points
    Nov 25, 2013 @ 23:24
    Bilal Isa
    0

    Hi Mads

    I ended up using umbraco.content.AfterUpdateDocumentCache. Thanks for your help.

    /Bilal

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 28, 2013 @ 15:27
    Mads Krohn
    0

    Hi Bilal

    No problem, hope everything turned out alright :)

    Cheers
    - Mads

  • andrew shearer 486 posts 609 karma points
    Nov 11, 2016 @ 04:57
    andrew shearer
    0

    how do i get the Url (i.e. Ipc) of a newly published item during the ContentService.published event?

  • Mads Krohn 211 posts 504 karma points c-trib
    Nov 14, 2016 @ 08:26
    Mads Krohn
    0

    Hej Andrew

    This is a very old topic. Did you not find anything useful in it? If not, please be a bit more specific about your problem.

    Cheers Mads

Please Sign in or register to post replies

Write your reply to:

Draft