SaaS CMS has officially launched! Learn more now.

Safest method of obtaining ContentReference from LinkItem

Vote:
 

Hi all,

I'm interested in your view on the following. In certain circumstances it is useful for us to know whether the LinkItem's within a LinkItemCollection are internal objects i.e. pages/assets etc stored in EPiServer. For sometime we've had this method in our library:

public static ContentReference ToContentReference(this LinkItem linkItem)
        {
            if (linkItem == null)
                return ContentReference.EmptyReference;

            var urlBuilder = new UrlBuilder(linkItem.Href);
            return PermanentLinkMapStore.ToMapped(urlBuilder)
            ? PermanentLinkUtility.GetContentReference(urlBuilder)
            : ContentReference.EmptyReference;
        }

However, when I ran some tests on it today I found that even though PermanentLinkMapStore.ToMapped(urlBuilder) returned true, indicating it could map the Url to an internal object, PermanentLinkUtility.GetContentReference(urlBuilder) still returned an empty ContentReference - which seems incredibly strange to me.

So I've re-written it to the following. I'm not as happy with it as it has a dependency on the ContentLoader however it does seem to work:

private ContentReference ToContentReference(LinkItem linkItem)
        {
            if (linkItem == null)
                return ContentReference.EmptyReference;

            var urlBuilder = new UrlBuilder(linkItem.Href);
            var map = PermanentLinkMapStore.Find(urlBuilder);
            if (map == null)
                return ContentReference.EmptyReference;

            var guid = map.Guid;
            var content = _contentLoader.Get(guid);
            return content == null ? ContentReference.EmptyReference : content.ContentLink;
        }

Interested to hear youir thoughts.

Thanks in advance

Al

#119269
Mar 25, 2015 17:19
Vote:
 

This is strange indeed. Can you paste one of internal mapped Urls?

#119276
Mar 25, 2015 22:08
Vote:
 

If you're on EPiServer 8, you should use the UrlResolver:

var content = UrlResolver.Current.Route(new UrlBuilder(linkItem.Href))

You also need to null-check content before returning content.ContentLink.

#119279
Mar 26, 2015 4:53
Vote:
 

Thanks Johan, you have made me learn something new, that is a nice way to solve this.

Do you know if it works in 7.5 also?

#119280
Mar 26, 2015 7:39
Vote:
 

Hi guys,

Valdis - all of these links fail to return a ContentReference using the original method. They all returned a valid ContentReference in 7.5 so I'm not sure what's happened, but it is a concern!

  • <a href="~/link/d8c9f56acb3d4980a3855b3038e54bc9.aspx">Test 1</a>
  • <a href="~/link/b130c0e0fd734b799521dfb57253dd02.aspx">Test 2</a>
  • <a href="~/link/a1e5326815a04cc6add1718ff3f563f1.aspx">Test 3 </a>

Johan - that method works a treat. Thankfully we're in a position to upgrade our own nuget libraries to version 8, so I now have two simplified methods to cover LinkItem and Url:

public static ContentReference ToContentReference(this LinkItem linkItem)
        {
            if (linkItem == null)
                return ContentReference.EmptyReference;

            var content = UrlResolver.Current.Route(new UrlBuilder(linkItem.Href));
            return content != null ? content.ContentLink : ContentReference.EmptyReference;
        }

And

public static ContentReference ToContentReference(this Url url)
        {
            if (url == null)
                return ContentReference.EmptyReference;

            var content = UrlResolver.Current.Route(new UrlBuilder(url));
            return content != null ? content.ContentLink : ContentReference.EmptyReference;
        }

Thanks for your help guys. Still very interested to know why this broke in 8. I can't say I analyse all of the Release notes as much as I might, but it seems a fairly fundamental piece of the core of EPiServer that now works differently.

Al

#119288
Mar 26, 2015 11:05
Vote:
 

Mapped links are gone in EPiServer 8. That's why your first method fails on PermanentLinkMapStore.ToMapped(). Your second method finds the permanent link, which stil works.

This information was in the documentation under breaking changes :)

#119300
Edited, Mar 26, 2015 14:19
Vote:
 

In which case...tut tut to me for not not viewing the release notes properly. However, if that's the case I would have expected the ToMapped and TryToMapped methods to have been marked obsolete, or perhaps even removed entirely if they no longer work - do you think so? Perhaps I should raise this.

Thanks again

Al

#119302
Mar 26, 2015 14:25
Vote:
 

It has been discussed here as well http://world.episerver.com/Modules/Forum/Pages/Thread.aspx?id=117930. But please ping the product guys, because I didn't get an answer when I raised the problem with functions related to mapped links.

#119308
Mar 26, 2015 15:46
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.