If you are developing custom SharePoint applications there is a good chance that you are going to need some custom web services at some point, especially if you are making use of AJAX and JSON.  There is a great walkthrough over on MSDN on how to do this, but if you just need a web service to enable AJAX on a page it is a bit of overkill, especially since there is no way to automate deployment on some of the steps they detail.  I also recently saw a presentation where the presenter put his custom web service in a separate web application, I’m going to show that this really isn’t necessary, and you can fully automate your web service deployments through solution packages.  In the long run this method of deployment will make your life much easier.

 

I use WSPBuilder for all my SharePoint development.  I know there are other tools out there but I’ve been using WSPBuilder since 2007 and it hasn’t failed me yet (Thanks Carsten!).  Why fix it if it ain’t broke?  For this reason I always structure my SharePoint projects in the WSPBuilder method, which mirrors the SharePoint 12 Hive.

The first thing you want to do is create a new class library and build out your folder structure.  You can use “wspbuilder – createfolders” to do this, but it will give you a bunch of folders you won’t need for this.  I opted to create mine by hand. 

You should then add a folder under “LAYOUTS” to separate your custom code from SharePoint out of the box code.

In the “LAYOUTS” folder you can add your .asmx file.  Unfortunately Visual Studio won’t let you add web services to a class library project, so I usually just add a text file, rename the extension, and add the appropriate markup inside the file.

You’ll also want to add the code behind file.  For the purposes of this sample I’ve kept them both in the same assembly, but they don’t have to be.  Here is what my project looks like so far.

image

Inside ServiceSample.asmx I have the following single line which tells the web service which code behind assembly and class to use:

<%@ WebService Language="C#" Class="CustomWebServiceSample.ServiceSample,CustomWebServiceSample,Version=1.0.0.0,Culture=neutral" %>

Inside ServiceSample.cs I have the following code:

public class ServiceSample : System.Web.Services.WebService
    {
        [WebMethod]
        public string GetServerName()
        {
            return HttpContext.Current.Server.MachineName; 
        }
        [WebMethod]
        public string GetCurrentSiteUrl()
        {
            return SPContext.Current.Web.Url.ToString();
        }
        
    }

  

The important thing to note here is that your SPContext will still be valid, as long as you enter the web service through the appropriate URL.  My development machine is named wssdev, so if I go to the web service through http://wssdev, I’ll get the context for the root site collection.  If I go to the service through http://wssdev/sites/<sitename>, I’ll get the context for that site collection. 

I have a post build script that copies my assembly and .asmx file to the appropriate location, if you package this using wspbuilder you won’t have to do this step, but it helps during development.  Here is the script:

@SET TEMPLATEDIR=c:\program files\common files\microsoft shared\web server extensions\12
xcopy /e /y bin\debug\CustomWebServiceSample.dll %BINDIR%
xcopy /e /y /q 12\* "%TEMPLATEDIR%"

Compile, build/deploy your wsp, or run the post build script, and you should be ready to go.

image

 

It really is that simple to deploy your custom SharePoint web services.  The important take aways here is that this works with standard solution package deployment and is very simple as opposed to some of the much more complex ways I have seen people doing this.