Connecting to a SharePoint 2013 site with CSOM via IP Address

During a recent project, my team and I built a custom console application with CSOM to sync taxonomy terms from one SharePoint environment to another.  During the project, we were introduced to a new requirement in this application: the ability to connect via IP address instead of via URL.

Our client is migrating and rebuilding their existing public-facing website (which I’ll refer to as Prod1) to a new server, which will ultimately have the same URL (Prod2).  For the time being, Prod2 will have a hosts file entry for 127.0.0.1 so we can deploy and access the site via the website’s URL (such as www.contoso.com).  When the deployment to Prod2 is complete, the intention is to point the public DNS over to Prod2 to avoid downtime.

However, the hosts file entry makes it impossible to access Prod1 by the www.contoso.com URL without manual intervention.  Therefore, we must connect to Prod1 by its IP address.

The issue is a little more complicated than just performing a find-replace on www.contoso.com and replacing it with an IP address.  Since we’ve created www.contoso.com as a Host-Name Site Collection in SharePoint, plugging in the IP address of Prod1 won’t actually connect us with the correct site collection.  Instead, we’ll get the root site collection (which on Prod1, is a blank template).  I started doing some research to see if we could manually specify the Host Header during our ClientContext instantiation.

I eventually stumbled upon the member ExecutingWebRequest inside the ClientContext class (inherited from ClientRuntimeContext), which allows one to specify certain HTTP Headers, including Host!  Shout out to Wictor Wilén and his blog post which demonstrated how to manually specify a HTTP User Agent in an ExecutingWebRequest.  Swap our User Agent for Host, and we’re in business!  Here’s the code block I ended up using to solve the issue:

var ctx = new ClientContext("http://<IP ADDRESS>")
{
    Credentials = new NetworkCredential(
        "<username>","<password>","<domain>"),
};

ctx.ExecutingWebRequest += (s, e) =>
{
    e.WebRequestExecutor.WebRequest.Host = "www.contoso.com";
};
var web = ctx.Web;
ctx.Load(web);
ctx.ExecuteQuery();

 

And a bonus: if you’re working with a subsite or a site collection under /sites/, (such as www.contoso.com/sites/TeamSite), you can just tack that on to the IP URL like so:

var ctx = new ClientContext("http://<IP ADDRESS>/sites/TeamSite")

The same goes for specifying a port:

var ctx = new ClientContext("http://<IP ADDRESS>:8080/")

And that’s it! If you found this post interesting, feel free to leave a comment below.

Leave a Reply