Need to write an HTTP server , can i use a webservice with "NOSOAP"?

J

jens Jensen

Hello,
I got this "breath taking" task to write a an http server to which "xml
data" will be posted to and will answer with xml data.
The logic behind the xml processing is not a matter here.

My question is : Can i configure a webservice for HHTP POST ?

The remote peer just performs an http web request.
NO RPC style call to my system.


How then can i authenticate with username and password?


Would it be better no to use webservice.

Where can i see good examples of http servers with authentication written in
C#?


Any help will be very much appreciated.


JJ
 
M

Marc Gravell

Well, you could just post to an ashx; pretty easy to setup - simply read
from the Request and write to the Response...

Marc
 
J

jens Jensen

Marc Gravell said:
Well, you could just post to an ashx; pretty easy to setup - simply read
from the Request and write to the Response...

Marc

This sounds great!

Can you give more info on where to read about this!
 
M

Marc Gravell

Easiest thing is just to create a new (empty) web-site, add an ashx (generic
handler), and play with it; for example (writes, doesn't read - but easy to
do using Load and the Request.InputStream) see below. Note that for large
xml (in the Mb range) you may wish to avoid the XmlDocument class, as it has
a performance (mainly memory) overhead; using XmlReader / XmlWriter is far
more efficient, but also (much) trickier to get right. XmlDocument is fine
for small to mid-size xml, plus it gives you XPath / XQuery.

Hope this helps,

Marc

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/xml";
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(@"<Test Of=""Some""><Xml/></Test>");
doc.Save(context.Response.OutputStream);
}

public bool IsReusable {
get {
return false;
}
}

}
 
M

Marc Gravell

To your other questions:
How then can i authenticate with username and password?

For this type of approach without SOAP? If you are using SSL, one option for
username / pw is to just use credentials in the XML - i.e.

<SomeMessage cn="who" pw="whatever">
<!-- blah -->
Would it be better no to use webservice.

Not if it doesn't meet the requirement ;-p
I have happily used this approach for inter-business communications without
any hitches; sometimes it was our design, sometimes theirs, so it isn't just
me...
But yes, web-services do give you many other options, in particular for
security and schema definition. Also handy if you don't have direct
line-of-sight between client and server, but this isn't very common.
... to write a an http server ...

Can you not just use IIS? If you do actually need to write the server, then
you can do a lot with the HttpListener class... but I wouldn't unless I
really had to ;-p (the main time I have used this is for client-side things
similar to how google desktop search works...)
 
J

jens Jensen

Marc

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/xml";
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(@"<Test Of=""Some""><Xml/></Test>");
doc.Save(context.Response.OutputStream);
}

public bool IsReusable {
get {
return false;
}
}

}

This looks amazingly like what i need. If the user sends a client
certificate.
can i use the code below here?

ServicePointManager.ServerCertificateValidationCallback += new
System.Net.Security.RemoteCertificateValidationCallback(ValidateServerCert);



Many thanks
JJ
 
M

Marc Gravell

No idea, sorry. I haven't had the need / opportunity to play with client
certificates in this context. It can probably be done, though. I would first
look at MSDN2 and google.

Anybody [else] out there experienced with such?

Marc
 
J

jens Jensen

public class Handler : IHttpHandler {

This looks great.

Can i deploy it like any other website?
 
M

Marc Gravell

Yup; it's just a page; as long as the web server supports asp.net it should
workm just fine; can deploy either as a standalone page, or as precompiled

(caveat: it /might/ work in 1.1 (I simply haven't tried), but certainly
works in 2.0)

Marc
 
J

jens Jensen

How do i actually produce a response from an httphandler.

I get error: (405) Method Not Allowed
 
M

Marc Gravell

Well, what is the "method"? GET, POST? what?

And how are you seeing the error?

The following works with the previous code via GET (obviously change the
uri):

static void Main(string[] args) {
XmlDocument doc = new XmlDocument();
using (WebClient client = new WebClient()) {
using(Stream stream =
client.OpenRead("http://localhost:1133/WebSite1/Handler.ashx")) {
doc.Load(stream); }
}
Console.WriteLine(doc.OuterXml);
}

A few quick tests POSTing with UploadData proved abortive, but I am pretty
certain you can use HttpWebRequest to do this; more code, though...

Marc
 
J

jens Jensen

I'm using
System.Net.WebResponse resp = (HttpWebResponse)req.GetResponse();

with a given uri.
 
M

Marc Gravell

This seems to work with the previously posted ashx running on the standard
web-server:

// GET
HttpWebRequest req = (HttpWebRequest)
WebRequest.Create("http://localhost:1133/WebSite1/Handler.ashx");
req.ContentType = "text/xml"; // maybe a white lie... ;-p (since
no body)
HttpWebResponse resp = (HttpWebResponse) req.GetResponse();
XmlDocument doc = new XmlDocument();
using (Stream fetched = resp.GetResponseStream()) {
doc.Load(fetched);
}
Console.WriteLine(doc.OuterXml);

// POST
req =
(HttpWebRequest)WebRequest.Create("http://localhost:1133/WebSite1/Handler.ashx");
req.ContentType = "text/xml";
req.Method = "POST";
doc.LoadXml("<Something><Posted/></Something>");
using (Stream post = req.GetRequestStream()) {
doc.Save(post);
}
resp = (HttpWebResponse)req.GetResponse();
using (Stream fetched = resp.GetResponseStream()) {
doc.Load(fetched);
}

Console.WriteLine(doc.OuterXml);
Console.ReadLine();
 
J

jens Jensen

doc.LoadXml( said:
using (Stream post = req.GetRequestStream()) {
doc.Save(post);
}
resp = (HttpWebResponse)req.GetResponse();
using (Stream fetched = resp.GetResponseStream()) {
doc.Load(fetched);
}

Console.WriteLine(doc.OuterXml);
Console.ReadLine();
I think io was missing the ahsx filename in my url.


Will try again
 
J

jens Jensen

Hi Marc,

Have you ever encountered any (404) not found error while connecting to the
"httphandler"?

below my code: (message contain a clob xml retreived from an oracle db)

HttpWebRequest req =
(HttpWebRequest)HttpWebRequest.Create(ConfigurationManager.AppSettings["URI"]);


req.ContentType = "text/xml; charset=utf-8";

req.Method = "POST";

UTF8Encoding encoding = new UTF8Encoding();

byte[] postBytes = encoding.GetBytes(message);

req.ContentLength = postBytes.Length;

System.IO.Stream reqStream = req.GetRequestStream();

reqStream.Write(postBytes, 0, postBytes.Length);

reqStream.Close();

System.IO.File.WriteAllBytes("BeingSent_"+message_id.ToString() +
"PostData.xml", postBytes);




System.Net.WebResponse resp = (HttpWebResponse)req.GetResponse();



System.IO.StreamReader sr = new
System.IO.StreamReader(resp.GetResponseStream());

message = (sr.ReadToEnd().Trim()).ToString();
 
M

Marc Gravell

Well, if I did, the first thing I would do is write the URI to either Debug
or Console, and then try and hit it separately... it often means that *it
isn't there* ;-p

If the file is physically there but unreachable, then you might want to
check security and web.config; for instance, are you using a
HttpNotFoundHandler (or whatever it is called) for anything, or is your
handler under App_Code or something else unreachable. Also maybe IIS
security settings, and ISAPI filters (URLScan for instance), etc.

Marc
 
J

jens Jensen

You are i correct, i get the same answer with IE:

http://localhost/server/handler.ashx



Server Error in '/' Application.
--------------------------------------------------------------------------------

The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) could have been removed, had its name changed, or is
temporarily unavailable. Please review the following URL and make sure that
it is spelled correctly.

Requested URL: /server/handler.ashx
 
M

Marc Gravell

Are you running through IIS or Cassini? (Cassini is the virtual web-server
that ships with VS2005, and which is the default for web-projects running
through the IDE)

If Cassini, you will need to include the port number in the URI, as Cassini
does not default to port 80 - and IIRC Cassini only supports local requests
(which, OK, is the case in your example).

See the URIs in my earlier post for an example of this; note that Cassini
has a habit of generating the port numbers dynamically - although they can
be fixed within a solution. The best option is to run the web-site through
IIS if you have it installed. The IIS thing can still be done through VS2005
(including breakpoints etc), as long as you:
a: Make sure that IIS has a suitable path (URI) mapped to your working
project folder
b: Make sure that VS2005 knows what this URI is in the "Use custom server"
option in the "Start Options" for the web-project

Any use?

Marc
 
M

Marc Gravell

Of course, the best way to get the correct URI is to right-click on the ashx
in the IDE and select "View in Browser"; no copy/paste the URI from IE ;-p

Marc
 

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

Top