How do I create a HttpHandler for a WebService(s)?

S

Sky

Hello:

Was excited last month with the options that are opened up by understanding
how HttpHandlers work --- works great for my new Image and JS resource
server so that i can compile server controls with all parts/pieces
incorporated directly into the assembly....

But now I want to push it a lot further: one thing I would really like to do
is be able to work with webservices -- but I want to do so without requiring
a page to listen to it so that webservices can also incorporated directly
into the control assembly.

My concerns center around what format/what exactly must I do with the
Request stream to be able to parse it, to know what method the client is
requesting access to, and then direct it to it.
Once passed that hurdle, can I hook up several WebServices to the same
handler? How do I direct them to the right one?
What do I have to do to 'correctly' integrate the webservice -- do I have to
modify the disco file as well, or is that done for me automatically at
compilation time? If so, how/what suggestions as to making the
modifications work?


Many many thanks in advance,
Sky
 
S

Saurabh Nandu

hi,

I have not tried this, but it should work this way. Basically Web Services even in todays framework works using HttpHandlers. The default HttpHandler for Web Services is System.Web.Services.Protocols.WebServiceHandlerFactory. Its configured in the machine.config.

This handler takes care of intercepting the request, then looking at the relevant method call as well as transforming the XML payload into .NET objects. Once that's done it must be using reflection to invoke the necessary method and pass the parameters to it.

If you want to write your own handler then you will have to take care of all this. Although then you have the freedom to come with with custom ways to invoke multiple methods on a single request etc. Also once you replace the defulat handler with your custom one, you can configure this for a single virtual application in the web.config in which case all the web services in that virtual directory will be served using your custom handler. Or if you make the change in the machine.config file then all the web services will be served using the custom handler.

It will be a good idea to use a dissassembler like .NET Reflector and look at the various functions the default web services handler does to get a fair idea of the work involved!
 
S

Sky

Hi Saurabh -- thanks for getting back to me so quickly :)

I've looked up the 'System.Web.Services.Protocols.WebServiceHandlerFactory'
you mentioned...and was disappointed to see that it was not intended to be
inherited from :-( so I don't know the 'magic' by which it parses the
incoming soap envelope to decide which class to call -- or how to wrap up
the response.

I tried of course -- but strangely enough the handler wasn't called at all
in that case -- only seems to work if creating one from scratch with
IHttpHandler...

Anyway -- so it appears that if the incoming POST is:
POST /TestXAC/service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>And you make a IHttpHandler derived class -- you sort of end
up in the same place...parsing by hand.


public void ProcessRequest(HttpContext hc) {


XmlDocument oRequest = new XmlDocument();

System.IO.StreamReader tSR = new StreamReader(hc.Request.InputStream);

string tIncomingXML = tSR.ReadToEnd(); if
(tIncomingXML){oRequest.LoadXml(tIncomingXML);}

....



But looking at the payload I can find the name of the function
("HellowWorld") -- but not the class/namespace that it is in
("Service1")....
So I am wondering what to do at that point -- think it could be that I have
to reflect over ever single Method in the assembly looking for a WebService
Attribute? Yikes...
I notice that in VS2003 there is a new Namespace= attribute that can be
stuck on the webservice -- but that wasn't implemented in VS2000 it apears
(atleast can't find it on my docs or get it accepted by the compiler).


I guess that I could assume that the URL requested could hold the key? Maybe
if the path requested was MyServices.Service1.asmx -- I could assume that
the class being asked for is 'Service1' ? Which brings me just a little
closer...
Then if the class is a webservice I have to...what?

So if we are parsing -- and MS was parsing -- what classes were they using
to help them?
How/What tools/helper classes can I invoke to correctly parse the XML to get
the vars to pass to the function HelloWorld(string qUserName) -- and then
wrap up the return stuff? I noticed one article pointing to stuff -- but it
looked definatly Framework II, not 1.0, or 1.1 -- know of any such beasts?
I guess I could do it myself -- but SOAP seems to be fast evolving protocol,
several flavours -- this could cause a lot of bugs later on down the road...


Thanks again,
Sky


Before I go -- let me ask the question a different way -- in case I missed
the bus earlier --... My investigation started out originally when I thought
of making a custom control for DotNetNuke (DNN) that relied on
S/Services -- but their modules have a specific installation methodology --
basically around a couple of ascx pages. No services pages allowed/taken
into account unless you do it manually. On my own web server I could fiddle
and force it in -- but for many others, with no access/little understanding,
I don't want to force them to have to install files that are beyond the
basic DNN recommended structure. Hence my desire for 'pageless'
installations...ie Handlers.

My question is ... is there an easier way to use one IHttpHandler (or other
technology) to handle several different webservice Classes, and Methods
therein? Without having to rewrite the whole wheel?








Saurabh Nandu said:
hi,

I have not tried this, but it should work this way. Basically Web Services
even in todays framework works using HttpHandlers. The default HttpHandler
for Web Services is System.Web.Services.Protocols.WebServiceHandlerFactory.
Its configured in the machine.config.
This handler takes care of intercepting the request, then looking at the
relevant method call as well as transforming the XML payload into .NET
objects. Once that's done it must be using reflection to invoke the
necessary method and pass the parameters to it.
If you want to write your own handler then you will have to take care of
all this. Although then you have the freedom to come with with custom ways
to invoke multiple methods on a single request etc. Also once you replace
the defulat handler with your custom one, you can configure this for a
single virtual application in the web.config in which case all the web
services in that virtual directory will be served using your custom handler.
Or if you make the change in the machine.config file then all the web
services will be served using the custom handler.
It will be a good idea to use a dissassembler like .NET Reflector and look
at the various functions the default web services handler does to get a fair
idea of the work involved!
--
Regards,
Saurabh Nandu
Master C#, the easy way...
[ www.MasterCSharp.com ]



Sky said:
Hello:

Was excited last month with the options that are opened up by understanding
how HttpHandlers work --- works great for my new Image and JS resource
server so that i can compile server controls with all parts/pieces
incorporated directly into the assembly....

But now I want to push it a lot further: one thing I would really like to do
is be able to work with webservices -- but I want to do so without requiring
a page to listen to it so that webservices can also incorporated directly
into the control assembly.

My concerns center around what format/what exactly must I do with the
Request stream to be able to parse it, to know what method the client is
requesting access to, and then direct it to it.
Once passed that hurdle, can I hook up several WebServices to the same
handler? How do I direct them to the right one?
What do I have to do to 'correctly' integrate the webservice -- do I have to
modify the disco file as well, or is that done for me automatically at
compilation time? If so, how/what suggestions as to making the
modifications work?


Many many thanks in advance,
Sky
 
S

Saurabh Nandu

My question is ... is there an easier way to use one IHttpHandler (or other
technology) to handle several different webservice Classes, and Methods
therein? Without having to rewrite the whole wheel?
</Quote>

None that i have heard of :) .. may be an oppertunity for you to make one available for the community .. hehehe
 
S

Sky

SlaveDriver =:)

Not exactly the week to start something new...
but I'll look into it over the weekend and drop a line in this forum
when(if?) I get it done :)

Best,
Sky



Saurabh Nandu said:
</Quote>

None that i have heard of :) .. may be an oppertunity for you to make one
available for the community .. hehehe
--
Regards,
Saurabh Nandu
Master C#, the easy way...
[ www.MasterCSharp.com ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,133
Latest member
MDACVReview
Top