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:
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.
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.
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;
}
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.
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.
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:
Thanks,
Alex
The key difference (
*boom tish*
) is that the one that is apparently broken will get the value from theumbraco.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:Note the
key
attribute after theid
attribute. If you don't see that, try deleting the file and recycling your app pool so that it gets regenerated.Hi Nicholas
Thank you for response, I checked umbraco.config and key attribute is filled with right Guid, but "IPublishedContent.GetKey()" doesn't work.
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:
I suspect it is something similar from IPublishedContent, although you might be able to cast it directly I'm not sure.
Nik
Hi Nik
Model.Content.GetKey() returns emty Guid too.
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:
Thanks,
Nik
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#L25Seems 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.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
Thanks, Nik!
No problem at all, it took me an age to figure it out myself. Happy to share to save the headaches :-)
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:
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
fromIPublishedContent
:The following method should guarantee to return a GUID key from
IPublishedContent
:The following extension method should return a UDI from
IPublishedContent
:You'll need to include the
Umbraco.Core
namespace.Hi Dan,
I am trying to use you code snipped but having trouble getting it to work. VS does not recognize
even though I use the
Any ideas what I could do?
Thanks
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 theMyProject.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.
Hi Dan,
thank you very much for your reply. I will definitely look into this.
Have a great day.
is working on a reply...