You only have an instance of Item.
How do you get it's "official" site, assuming there are multiple Sites defined in configuration?
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.
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.
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
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.
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.