Working with HTTP Module and Host-Named Site Collection


Writing is the one of the listed “Hobbies” on my resume but I never tried my hand on blog before. So recently while working for a client I came across problem with Http Module and it took me days of efforts to figure out the solution which was there all the time and I just needed to think of the basics. So the scenario was that we were using an Http Module to redirect requests. We had a list which stored the redirect pointers. Everything was working just fine till we tested the code on a Host-Named Site Collection and the functionality just stopped working. The requests were not going through the Http Module. As you might know how Host-Named Site Collection URL looks like, to give you a brief Host-Named Site Collection enable you to assign a unique DNS name to site collections in SharePoint. For example, you can address them as http://may.sp.com:90000  and http://fair.sp.com. So let’s just say that http://may.sp.com:90000 is my root Host Name Site Collection and this is my SharePoint Web Application name as well. So when I tried my functionality on http://may.sp.com:90000 it worked just fine but on http://fair.sp.com, the requests were not going through. After days of googling I came across this blog http://blogs.msdn.com/b/kaevans/archive/2012/03/27/what-every-sharepoint-admin-needs-to-know-about-host-named-site-collections.aspx in which it is explained that if my Web Application is not hosted on port number 80 as in my case it’s on 90000 then all of my Host Name Site collections need to be on 90000. So I crossed my fingers and added a Binding in IIS and hurrah!! it worked.
There are many ways of doing it but here I am including the manual method and one in which I used a DirectoryEntry class of c#.

Manual Method:
Open IIS, expand your server and locate your web application under sites. Here for example say we are using TPLogin.


On the right side you will see Bindings, click on that and click on Add.



Then you will see a screen as show below, here add your Host-Named Site Collection name and  other details like port and type of protocol or you might want to assign IP.


Click on OK and you are done.

Doing it programmatically:
Now let’s see how to do this programmatically, I here have used DirectoryEntry Class of c#. I have made AddHostHeader function which takes arguments like your port number, hostname, web application name and your server name. All this can be easily retrieved from SPSite object. I called this method on feature activation on the Host-Named Site Collection.

void AddHostHeader(int port, string hostname, string webApp, string serverName)
        {
            DirectoryEntry w3svc = new DirectoryEntry(string.Format("IIS://{0}/w3svc", serverName));
            foreach (DirectoryEntry site in w3svc.Children)
            {
                if (site.Properties["ServerComment"] != null)
                {
                    if (site.Properties["ServerComment"].Value != null)
                    {
                        if (string.Compare(site.Properties["ServerComment"].Value.ToString(),
                                             webApp, false) == 0)
                        {
                            Console.Write(int.Parse(site.Name));
                            var bindings = site.Properties["ServerBindings"];
                            var header = string.Format("{0}:{1}:{2}", "", port, hostname);
                            if (bindings.Contains(header))
                                return;
                            bindings.Add(header);
                            site.CommitChanges();
                            break;
                        }
                    }
                }
            }
        }
Here I have used “ServerComment” property, as in IIS the name of the web application is stored there. You might also want to check that if the site collection in question is a Host-Named Site Collection or not you can do that by using SPSite.HostHeaderIsSiteName property.
Before using this code you must make sure that the person running this code is a local admin, has permissions to make changes in IIS, he must be part of IIS_IUSRS group or you might also think of impersonating the user who has all these rights else the code may run with ‘NT AUTHORITY\IUSR' account as it first did in my case first.

I hope this blog was helpful to you.

Thanks for reading.





Comments

Popular posts from this blog

PnP Modern Search Extensibility: Creating Custom Layouts

PnP Modern Search Extensibility: Creating Handlebar Helpers

PnP Modern Search Extensibility