4

I am trying to get "http://hostname" in below way.

string.Concat(Request.Url.Scheme, Uri.SchemeDelimiter, Request.Url.Host)

this should work in normal cases, but i am doing this on publish:end event, where request is null.

The context site is publisher and could not find Request property in EventArgs whats the best way to get Request properties in this case?

1
  • There are no request properties, as there is no request currently executing. Jan 27, 2017 at 0:06

2 Answers 2

15

The problem with Sitecore.Context.Site:

Sitecore performs publishing on the publisher site, and as you noted, the publish:end is an event and is called without a request, so there isn't even a URL to work from.

Based on the above, hypothetically, if we assume that Sitecore is going to resolve a site (we don't know which yet) to put in the Sitecore.Context then the website (or custom site) that you're looking for isn't even a candidate.

Working towards getting the site:

Every item in Sitecore is site-specific, in that it's path should only ever live within a single site. The publish:end event just so happens to have a handy little Publisher object as a parameter, that holds the RootItem that was published. You can access this item and the Site it belongs to by doing the following in your event handler:

...
var scArgs = args as Sitecore.Events.SitecoreEventArgs;     
if (scArgs == null)
{
    return;
}

var publisher = scArgs.Parameters[0] as Publisher;     
if (publisher == null)
{
    return;
}

var rootItem = publisher.Options.RootItem;
var site = Sitecore.Configuration.Factory.GetSiteInfoList()
    .FirstOrDefault(site => rootItem.Paths.FullPath.StartsWith(site.RootPath));
...

But wait! What about multi-site publishes?

What if you published more than one site? Now you will match the first one, when you should probably return both or return null. On the flip side, what if you published the full solution and have only one site, or else you published the full solution and now you want to get all sites that you published? The above will give you null in these cases, but maybe that's not what you want.

Getting the site with multi-site publishing support:

In order to support multi-site and situations where you may have published the full solution, update the above to the following:

...
var scArgs = args as Sitecore.Events.SitecoreEventArgs;     
if (scArgs == null)
{
    return;
}

var publisher = scArgs.Parameters[0] as Publisher;     
if (publisher == null)
{
    return;
}

var rootItem = publisher.Options.RootItem;
var publishedSites = Sitecore.Configuration.Factory.GetSiteInfoList()
    .Where(site => rootItem.Paths.FullPath.StartsWith(site.RootPath));
...

We aren't done yet, however. You still don't have the URL of the site.

Solution: Getting the URL of the published site(s)

The site-definition nodes have the nifty little optional attributes targetHostName and scheme. Assuming that you have specified a value for those attributes, you can then retrieve the URLs of the sites of the sites you published by updating the above to the following:

...
var scArgs = args as Sitecore.Events.SitecoreEventArgs;     
if (scArgs == null)
{
    return;
}

var publisher = scArgs.Parameters[0] as Publisher;     
if (publisher == null)
{
    return;
}

var rootItem = publisher.Options.RootItem;
var publishedSites = Sitecore.Configuration.Factory.GetSiteInfoList()
    .Where(site => rootItem.Paths.FullPath.StartsWith(site.RootPath));

var publishedHosts = publishedSites
    .Select(site => site.Properties["scheme"] + @":\\" + site.Properties["targetHostName"]);
...
1
  • 1
    Not sure why this post was downvoted. It is normal for members to post an initial answer and update it in order to make it more thorough, which I had not stopped doing before it was downvoted. I gave an alternative and more direct solution to get the same result as the other posted answer, and then updated my post to even include the extra steps that would take the OP to the desired result. The code definitely works, and it's not the wrong way to do it, by any stretch. I guess I just don't like downvotes without comments... Jan 26, 2017 at 18:55
4

Using the Sitecore.Configuration.Factory.GetSite() method you can retrieve a Sitecore.Sites.SiteContext object that has properties defined that correspond to your site.

var siteContext = Sitecore.Configuration.Factory.GetSite("sitename");

Then from the siteContext item you can access the HostName or TargetHostName values depending on what you need.

9
  • Since publishing runs on the publisher site and events are raised from shell I'm fairly certain that this isn't going to work Jan 26, 2017 at 18:16
  • 1
    @ZacharyKniebel He's suggesting getting a specific named Site object using Factory, not using Context.Site... so it should work... get's a bit trickier in multi-site and it would only retrieve hostName/targetHostName for the CM instance...
    – jammykam
    Jan 26, 2017 at 18:29
  • Gotcha - I see what you're saying. You're goign to need to do some regex matching on site names in order to resolve the site. That would work :) Jan 26, 2017 at 18:32
  • 1
    The Factory also has a method (Sitecore.Configuration.Factory.GetSiteNames()) to get a list of the Site Names, which then could be used in tracking down the desired site to get the context for. There are other methods that can be used as well to retrieve site information.
    – BillCacy
    Jan 26, 2017 at 18:42
  • 1
    @DheerajPalagiri you should include that in the OP. Otherwise, your question is asking how to do that as well, which my solution provides an explanation for Jan 26, 2017 at 19:11

Your Answer

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

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