13

You only have an instance of Item.

How do you get it's "official" site, assuming there are multiple Sites defined in configuration?

3 Answers 3

16

Probably the most terse:

string itemPath = item.Paths.FullPath;    
SiteInfo site = SiteContextFactory.Sites
    .Where (s => s.RootPath !="" & itemPath.StartsWith(s.RootPath, StringComparison.OrdinalIgnoreCase))
    .OrderByDescending(s => s.RootPath.Length)
    .FirstOrDefault();

itemPath is factored out of the LINQ for performance.

3
  • 1
    What happens if two site definitions point to the same section of the content tree? Commented Oct 4, 2016 at 20:01
  • Without knowing more, You will probably have issues with site resolution! Assuming this actually works, the logic will pick the first available site definition every time, as will Sitecore when doing site resolution. The order of definitions is important. Commented Oct 10, 2016 at 13:44
  • @DerekDysart Sitecore resolves sites from top to bottom as they appear in Sitecore.config. So the first match wins. Check the final order of your site definitions at this url https://{yoursite}/sitecore/admin/showconfig.aspx
    – TxRegex
    Commented Aug 26, 2019 at 18:39
15

It's possible to determine the Site an item "belongs" to using the LinkManager. This is how Sitecore resolves links internally when Rendering.SiteResolving = true and expanding links or resolving the Preview Site when Preview.ResolveSite = true.

var item = Sitecore.Context.Database.GetItem("/sitecore/content/my-item");
SiteInfo site = Sitecore.Links.LinkManager.ResolveTargetSite(item);

Possibly not the best use of the LinkManager and it feels a little dirty as a result, but this mean that you follow the same logic as Sitecore and should something change in the future then your own code will follow that same logic.

3
  • 2
    I like this approach and it's probably the most "correct". Commented Oct 5, 2016 at 9:06
  • 2
    The issue with this approach is that LinkManager is a wrapper for what may be a custom LinkProvider, so who knows what you're going to get. I think both solutions have merit. Commented Oct 5, 2016 at 13:20
  • 3
    Yes, it's a good point. Depends of course if the default LinkProvider has been inherited and then this method also overridden. If you wanted to be doubly sure you were using the Sitecore provider a you could new up an instance of Sitecore.Links.LinkProvider and call ResolveTargetSite on that.
    – jammykam
    Commented Oct 5, 2016 at 13:36
2

I'm unaware in which version this was introduced but at least in Sitecore 9.3 the other answers are outdated and should be replaced by utilizing the IItemSiteResolver interface which you can get through dependency injection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.