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.
9 Comments
Comments have been disabled for this content.
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?
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.
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?
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.
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
hafees said
What is the WSType?
weblogs.asp.net said
Dynamically creating a sharepoint web service proxy instance.. Slap-up :)
weblogs.asp.net said
Dynamically creating a sharepoint web service proxy instance.. Huh, really? :)
Mccombs said
Hi there mates, nice piece of writing and pleasant arguments commented at this place, I am actually enjoying by these.