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?

  • There are no request properties, as there is no request currently executing. – Mark Cassidy Jan 27 '17 at 0:06
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
    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... – Zachary Kniebel Jan 26 '17 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.

  • Since publishing runs on the publisher site and events are raised from shell I'm fairly certain that this isn't going to work – Zachary Kniebel Jan 26 '17 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 '17 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 :) – Zachary Kniebel Jan 26 '17 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 '17 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 – Zachary Kniebel Jan 26 '17 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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