Copied to clipboard

Flag this post as spam?

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


  • Alex Skrypnyk 6132 posts 23951 karma points MVP 7x admin c-trib
    May 16, 2017 @ 22:29
    Alex Skrypnyk
    0

    Umbraco 7.6.1 IPublishedContent.GetKey() returns empty Guid

    Hello Community

    I'm using Umbraco 7.6.1 and have an issue - IPublishedContent.GetKey() method returns an empty Guid, but it works via ContentService:

        var node =
    ApplicationContext.Services.ContentService.GetById(someId);
    
        var id = node.Key;
    

    Thanks,

    Alex

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    May 17, 2017 @ 00:40
    Nicholas Westby
    2

    The key difference (*boom tish*) is that the one that is apparently broken will get the value from the umbraco.config file. If you recently did an upgrade, I could see that file having not been updated to add keys to each XML element. In particular, each XML element that represents a page in that file should look something like this:

    <someDoctype id="1111" key="11111111-1111-1111-1111-111111111111" parentID="-1" level="1" creatorID="1" sortOrder="0" createDate="2011-01-11T11:11:11" updateDate="2011-01-11T11:11:11" nodeName="Some Node Name" urlName="whatevs" path="-1,1111" isDoc="" nodeType="2222" creatorName="someUser" writerName="someUser" writerID="1" template="0" nodeTypeAlias="someDoctype">
    

    Note the key attribute after the id attribute. If you don't see that, try deleting the file and recycling your app pool so that it gets regenerated.

  • Alex Skrypnyk 6132 posts 23951 karma points MVP 7x admin c-trib
    May 17, 2017 @ 07:19
    Alex Skrypnyk
    0

    Hi Nicholas

    Thank you for response, I checked umbraco.config and key attribute is filled with right Guid, but "IPublishedContent.GetKey()" doesn't work.

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    May 17, 2017 @ 07:34
    Nik
    2

    Hi Alex,

    You need a second step in place to get the Key from IPublishedContent. You actually need to convert the IPublishedContent to an IPublishedContentWithKey. By default, the IPublishedContent doesn't store the key in an accessible manner until you do this.

    This is how I did it from a modelsbuilder model:

     var sectorWithKey = sector.Unwrap() as IPublishedContentWithKey;
    

    I suspect it is something similar from IPublishedContent, although you might be able to cast it directly I'm not sure.

    Nik

  • Alex Skrypnyk 6132 posts 23951 karma points MVP 7x admin c-trib
    May 17, 2017 @ 07:42
    Alex Skrypnyk
    0

    Hi Nik

    Model.Content.GetKey() returns emty Guid too.

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    May 17, 2017 @ 07:58
    Nik
    100

    Hi Alex,

    Yep, I would expect that as Model.Content (even if it is a converted model via models builder) is of type IPublishedContent.

    Try this:

     var modelWithKey = Model.Content.Unwrap() as IPublishedContentWithKey;
     var key = modelWithKey.GetKey();
    

    Thanks,

    Nik

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    May 20, 2017 @ 19:52
    Nicholas Westby
    1

    This is more or less what the GetKey extension method should be doing: https://github.com/umbraco/Umbraco-CMS/blob/9badb35c054ecc91630b69b1b6753c78427cb4a6/src/Umbraco.Web/PublishedContentExtensions.cs#L25

    public static Guid GetKey(this IPublishedContent content)
    {
        var contentWithKey = content as IPublishedContentWithKey;
        return contentWithKey == null ? Guid.Empty : contentWithKey.Key;
    }
    

    Seems like for some reason the underlying type may not be implementing IPublishedContentWithKey (or the original content is null). Maybe an Umbraco core bug? I suppose it may also depend on how the content node is retrieved.

  • Alex Skrypnyk 6132 posts 23951 karma points MVP 7x admin c-trib
    May 21, 2017 @ 20:24
    Alex Skrypnyk
    0

    Thanks Nicholas

    Yes, it looks like a bug, it will be logical to have Key property, and it shouldn't depend on how did you retrieve the data.

    Alex

  • Alex Skrypnyk 6132 posts 23951 karma points MVP 7x admin c-trib
    May 17, 2017 @ 11:39
    Alex Skrypnyk
    1

    Thanks, Nik!

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    May 17, 2017 @ 11:42
    Nik
    1

    No problem at all, it took me an age to figure it out myself. Happy to share to save the headaches :-)

  • Zac 223 posts 575 karma points
    Jun 21, 2017 @ 08:36
    Zac
    3

    I think this needs to be a simplified. Anyway, thanks to Nik and and Nicholas I created an extension method to make sure this would work from modelsbuilder objects as well as other content:

    public static Guid GetGuid(this IPublishedContent content)
    {
        var contentWithKey = content as IPublishedContentWithKey;
        if (contentWithKey != null)
            return contentWithKey.Key;
        if (content is PublishedContentWrapped)
        {
            contentWithKey = ((PublishedContentWrapped)content).Unwrap() as IPublishedContentWithKey;
            if (contentWithKey != null)
                return contentWithKey.Key;
        }
        return Guid.Empty;
    }
    
  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Jul 19, 2017 @ 08:47
    Dan Diplo
    4

    I created the following extension methods to make working with GUIDs and UDIs much less painful and reliable. Hope they help someone!

    The following extension method should return a IPublishedContentWithKey from IPublishedContent:

    /// <summary>
    /// Gets the published content with a guaranteed key
    /// </summary>
    /// <param name="content">The published content</param>
    /// <returns>A published content with key</returns>
    /// <remarks>
    /// Workaround for the fact that GetKey() doesn't always work - see http://issues.umbraco.org/issue/U4-10128
    /// </remarks>
    public static IPublishedContentWithKey GetContentWithKey(this IPublishedContent content)
    {
        var withKey = content as IPublishedContentWithKey;
    
        if (withKey != null)
            return withKey;
    
        var wrapped = content as PublishedContentWrapped;
    
        if (wrapped != null)
            return GetContentWithKey(wrapped.Unwrap());
    
        return null;
    }
    

    The following method should guarantee to return a GUID key from IPublishedContent:

    /// <summary>
    /// Guaranteed to return a GUID
    /// </summary>
    /// <param name="content">The published content</param>
    /// <returns>A Guid</returns>
    public static Guid GetKeyGuaranteed(this IPublishedContent content)
    {
        var contentWithKey = content.GetContentWithKey();
        return contentWithKey != null ? contentWithKey.GetKey() : Guid.Empty;
    }
    

    The following extension method should return a UDI from IPublishedContent:

    /// <summary>
    /// Gets an Umbraco UDI
    /// </summary>
    /// <param name="content">The published content</param>
    /// <param name="objectType">The type of UDI to create</param>
    /// <returns>An Umbraco Document Identifier</returns>
    public static Udi GetUdi(this IPublishedContent content, UmbracoObjectTypes objectType)
    {
        string type = Constants.UdiEntityType.FromUmbracoObjectType(objectType);
        return Udi.Create(type, content.GetKeyGuaranteed());
    }
    

    You'll need to include the Umbraco.Core namespace.

  • Edgar Rasquin 326 posts 925 karma points
    Oct 03, 2019 @ 09:31
    Edgar Rasquin
    0

    Hi Dan,

    I am trying to use you code snipped but having trouble getting it to work. VS does not recognize

    GetContentWithKey
    

    even though I use the

    @using Umbraco.Core
    

    enter image description here

    Any ideas what I could do?

    Thanks

  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Oct 03, 2019 @ 10:53
    Dan Diplo
    1

    Hi Edgar. The GetContentWithKey is an extension method I created. So you will first need to create a static class and add the methods shown in my post to it. Then you will need to reference it via the namespace you chose for the class. ie. if you put it in the MyProject.Extensions namespace you'd need to add @using MyProject.Extensions in your view.

    See https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members or https://www.c-sharpcorner.com/UploadFile/74ce7b/static-class-in-C-Sharp/ if you are not familiar with static classes.

  • Edgar Rasquin 326 posts 925 karma points
    Oct 03, 2019 @ 14:16
    Edgar Rasquin
    0

    Hi Dan,

    thank you very much for your reply. I will definitely look into this.

    Have a great day.

Please Sign in or register to post replies

Write your reply to:

Draft