There are so many examples of building custom web service for SharePoint. Unfortunatelly, the step includes modification of SharePoint built-in file (ISAPI\spdisco.aspx). This kind of modification is dangerous - especially when there is patch release by Microsoft; it will be overriden. Moreover, modifying SharePoint's built-in file leaving SharePoint farm in un-supported state.

Building the Sample

  1. Extract the package
  2. Double-click on the DemoCustomWS.sln
  3. Build and deploy the package.

This project requires Visual Studio 2010 and SharePoint 2010.


This solution offers different approach that basically avoid modifying spdisco.aspx. In order to do that there are couple things that we do:

  1. Create DemoWS.spdisco.aspx .
    Instead of registering our web service information in spdisco.aspx, we will list it in DemoWS.spdisco.aspx.
  2. Create custom HttpHandler to intercept request to _vti_bin/spdisco.aspx
    This HttpHandler will listen to _vti_bin/spdisco.aspx , process original spdisco.aspx and combine it with any *.spdisco.aspx. So in this case, it will return combination of spdisco.aspx and DemoWS.spdisco.aspx
  3. Create copy of spdisco.aspx into spdisco.disco.aspx
    This copy is important to avoid infinite-loop inside our HttpHandler.
  4. Modify web.config to register HttpHandler
    To modify web.config, we will create webconfig.DemoWS.xml and install it in CONFIG folder of SharePoint hive. Then, we can run stsadm -o copyappbincontent do merge it with web.config in any web application. 

Following diagram shows how the solution works:



The key of this solution is HttpHandler process which will intercepts all request to _vti_bin/spdisco.aspx and replacing with the new process. In the new process, the HttpHandler will combine spdisco.aspx and any other *.spdisco.aspx in the ISAPI folder.

public void ProcessRequest(HttpContext context) 
            StringWriter sw1 = new StringWriter(); 
            // Original - cop spdisco.aspx 
            context.Server.Execute("spdisco.disco.aspx", sw1); 
            XmlDocument spdiscoXml = new XmlDocument(); 
            var files = Directory.GetFiles(context.Server.MapPath(""), "*.spdisco.aspx"); 
            foreach (var file in files) 
                StringWriter sw2 = new StringWriter(); 
                context.Server.Execute(System.IO.Path.GetFileName(file), sw2); 
                XmlDocument otherSPDiscoXml = new XmlDocument(); 
                foreach (XmlNode importedNode in otherSPDiscoXml.DocumentElement.ChildNodes) 
                    spdiscoXml.DocumentElement.AppendChild(spdiscoXml.ImportNode(importedNode, true)); 
            context.Response.Write(String.Format("<?xml version='1.0' encoding='utf-8' ?> {0}", spdiscoXml.InnerXml)); 

Next important things is to register HttpHandler to the web.config.


<?xml version="1.0" encoding="utf-8" ?>  
  <add path="configuration" id="{24E2107B-6288-4C54-912D-3D5CE7BEEDE0}" 
    <location path="_vti_bin/spdisco.aspx" 
          <add name="DemoWSHandler" verb="*" path="*_vti_bin/spdisco.aspx" type="DemoWS.HttpHandler, DemoWS , Version=, Culture=neutral, PublicKeyToken=293c0f6de57e7690" />  
 The config will be distributed to CONFIG folder in SharePoint hive and merged into web.config using stsadm -o copyappbincontent command.



More Information

1. Writing Custom Web Services for SharePoint Products and Technology (
2. SharePoint Architecture ( )
3. Architectural Overview of Windows SharePoint Services (
4. Modifying Built-In SharePoint Files (
5. My blog - Ideas for Free (