Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating Web Services in a Class Library project

0.00/5 (No votes)
29 Nov 2007 1  
This article explains how you can create Web Services in a Class Library project

Introduction

Recently I worked on a plug-in based system, and one of the approaches of this system was to allow each plug-in (dll) to have the capability to host web services. I had never heard about such task before, I made a search on the Web and didn't find anything about that, so I decided to think and fortunately I came with a pretty good solution.

The HTTP Handler for .asmx

The first thing I did was to open the Web.Config file located in %windir%\Microsoft.NET\Framework\v2.0.50727\CONFIG and look at the following entry inside <httpHandlers>:

<add path="*.asmx" verb="*" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="False" />

Using Reflector, I found that the WebServiceHandlerFactory builds and returns an IHttpHandler in the GetHandler of the IHttpHandlerFactory interface, that was all I needed to know.

Creating the WebServiceBase class

So here it is what I did:

I created a new Class Library project and in this project, a class named WebServiceBase, this class could be anywhere, since it's an abstract class that will be the base class for the web services. The definition of this class is below:

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Reflection

Public MustInherit Class WebServiceBase
    Inherits WebService
    Implements IHttpHandlerFactory
    
    Private Shared wshf As New WebServiceHandlerFactory
    Private Shared coreGetHandlerMethod As MethodInfo = GetType(WebServiceHandlerFactory).GetMethod("CoreGetHandler", _
    BindingFlags.Instance Or BindingFlags.NonPublic)

    Public Function GetHandler(ByVal context As System.Web.HttpContext, ByVal requestType As String, ByVal url As String, _
    ByVal pathTranslated As String) As System.Web.IHttpHandler Implements System.Web.IHttpHandlerFactory.GetHandler
        Return DirectCast(coreGetHandlerMethod.Invoke(wshf, New Object() {Me.GetType, context, context.Request, context.Response}), IHttpHandler)
    End Function

    Public Sub ReleaseHandler(ByVal handler As System.Web.IHttpHandler) Implements System.Web.IHttpHandlerFactory.ReleaseHandler

    End Sub

End Class

Note the Reflection hack to call the CoreGetHandler method from WebServiceHandlerFactory, this is needed because this method is declared as Friend, and this method is the one that actually creates the IHttpHandler instance.

It's almost done! All you have to do now is create the web services, which will be classes that inherit from this one, so here is an example:

Imports System.Web.Services

<WebService(Namespace:="http://tempuri2.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class WSTest
    Inherits WebServiceBase

    <WebMethod()> _
    Public Function HelloWorld() As String
        Return "Hello World"
    End Function
End Class

Remember that everything above is in a Class Library, so compile this project, create a new web site and add this project as a reference.

This Class Library project I called WSLibrary, and as the WSTest is nothing more than a HttpHandler, you should add a new entry to your web.config for each Web Service you created, in this example above, I added:

<httpHandlers>
  <add path="WSTest.asmx" verb="*" type="WSLibrary.WSTest" validate="false"/>
</httpHandlers>

Now, every time a request to WSTest.asmx is made, it will be handled by the WSLibrary project. It can be changed very easily to suit your needs.

Conclusion

This approach worked very well for the project I was working on. I'm sure there are more things that could be made to make it even better, like you can make a way that only one entry in the httpHandlers is necessary for as many web services as you have.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here