Miscellaneous Debris

Avner Kashtan's Frustrations and Exultations

Dynamically creating a Sharepoint Web-Service proxy instance

In my current code, I find myself accessing many Sharepoint web services. In one run of code I can access 5-6 different web services on dozens of different sites, not necessarily even on the same server. Given that I find myself writing a lot of boilerplate code looking like this:

using (SiteData siteDataWS = new SiteData())
{
   siteDataWS.Credentials = CredentialsCache.DefaultNetworkCredentials;
   siteDataWS.Url = currentSite.ToString() + "/_vti_bin/SiteData.asmx";

   // Do something with the WS.
}

Seeing as this is quite wearisome, I've decided to go an genericize it. Given also that the name of the ASMX file for all Sharepoint services is the same as the name of the class to be instantiated, it gets even shorter:

1:  public static WSType CreateWebService<WSType> (Uri siteUrl) where WSType : SoapHttpClientProtocol, new()
2: {
3:    WSType webService = new WSType();
4:    webService.Credentials = CredentialCache.DefaultNetworkCredentials;

5:    string webServiceName = typeof(WSType).Name;
6:    webService.Url = string.Format("{0}/_vti_bin/{1}.asmx", siteUrl, webServiceName);

7:    return webService;
8: }

Line 1: Define a generic method that receives the type of Web Service and returns an instance of it. Note the generic constraints - the type must be a Web Service Proxy (SoapHttpClientProtocol) and must be instantiable. The last one is necessary for line 3 to compile.

Line 5: Get the name of the type - for our example above it would be "SiteData" - and build the URL based on the site URL and the web service name.

Now I can transform the above snippet to this:

using (SiteData siteDataWS = WebServiceHelper.CreateWebService<SiteData>(currentSite))
{
   // Do something with the WS.
}

Drastic change? No, not really. But it keeps things clean.

Comments

Christopher Bermingham said:

Neat method, thanks for posting it.  I have a question for you though, what is the advantage to using a "using" :) statement when instantiating a web service?

# September 4, 2007 9:15 AM

Avner Kashtan said:

That's a good question, actually. I tend to use it whenever I have an IDisposable object, assuming that if someone took the trouble of implementing IDisposable, I should make sure it's called.

In the case of web service proxies, it seems that IDisposable is simply a side effect of deriving ultimately from Component, and no actual interesting code is called in Dispose.

But I think I'll keep on using it.

# September 5, 2007 5:30 AM

Ajay Porwal said:

Do we need to have anything in Web Reference?

If no, then do you mean that, you are adding a web reference dynamically?

What if it is not a sharepoint web service?

# March 15, 2008 8:00 AM

Avner Kashtan said:

This technique assumes that you already have the Web Reference added to the project, otherwise it won't know what object to instantiate. It doesn't do any WSDL querying or the like, it's simply a shorthand for instantiating the proxy.

The trick here is assuming that the name of the proxy class ("Lists", "UserGroup") is the same as the name of the ASMX file on the server ("Lists.asmx", etc). This assumption works for Sharepoint web services, but might not be true for others. Other than that, there's nothing in the code that's Sharepoint-specific.

# March 15, 2008 1:27 PM

hafees said:

nice article,

I want acces the sharepoint web servcie to business class to fill the business object so how can I do it without web reference

# October 23, 2008 2:12 AM

hafees said:

What is the WSType?

# October 23, 2008 2:20 AM

weblogs.asp.net said:

Dynamically creating a sharepoint web service proxy instance.. Slap-up :)

# May 10, 2011 7:48 PM

weblogs.asp.net said:

Dynamically creating a sharepoint web service proxy instance.. Huh, really? :)

# June 24, 2011 5:43 PM

Mccombs said:

Hi there mates, nice piece of writing and pleasant arguments commented at this place, I am actually enjoying by these.

# November 18, 2012 11:22 AM