I\'m busy writing a class that monitors the status of RAS connections. I need to test to make sure that the connection is not only connected, but also that it can communica
How about opening a TCP/IP connection to the port used by the webservice? If the connection works, the RAS connection, the rest of the network and the host are all working. The webservice is almost certainly running too.
If it is a Microsoft SOAP or WCF service and service discovery is allowed, you can request the web page serviceurl + "?disco" for discovery. If what is returned is a valid XML document , you know the service is alive and well. A non-Microsoft SOAP service that does not allow ?disco will probably return valid XML too.
Sample code:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "?disco");
request.ClientCertificates.Add(
new X509Certificate2(@"c:\mycertpath\mycert.pfx", "<privatekeypassword>")); // If server requires client certificate
request.Timeout = 300000; // 5 minutes
using (WebResponse response = request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
{
XmlDocument xd = new XmlDocument();
xd.LoadXml(sr.ReadToEnd());
return xd.DocumentElement.ChildNodes.Count > 0;
}
If the web server is present, but the service does not exist, an exception will be raised quickly for the 404 error. The fairly long time-out in the example is to allow a slow WCF service to restart after a long period of inactivity or after iisreset. If the client needs to be responsive, you could poll with a shorter timeout until the service is available.
The tip: create a interface/baseclass with method "InvokeWithSomeParameters". The meaning of "SomeParameters" should be a "parameters which 100% does not affect any important state".
I think, there are 2 cases:
I don't think, this is most clear solution, but it should works.
You are right that pinging the server isn't sufficient. The server can be up, but the web service unavailable due to a number of reasons.
To monitor our web service connections, I created a IMonitoredService interface that has a method CheckService(). The wrapper class for each web service implements this method to call an innocuous method on the web service and reports if the service is up or not. This allows any number of services to be monitored with out the code responsible for the monitoring knowing the details of the service.
If you know a bit about what the web service will return from accessing the URL directly, you could try just using the URL. For example, Microsoft's asmx file returns a summary of the web service. Other implementations may behave differently though.
You could try the following which tests the web site's existence:
public static bool ServiceExists(
string url,
bool throwExceptions,
out string errorMessage)
{
try
{
errorMessage = string.Empty;
// try accessing the web service directly via it's URL
HttpWebRequest request =
WebRequest.Create(url) as HttpWebRequest;
request.Timeout = 30000;
using (HttpWebResponse response =
request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception("Error locating web service");
}
// try getting the WSDL?
// asmx lets you put "?wsdl" to make sure the URL is a web service
// could parse and validate WSDL here
}
catch (WebException ex)
{
// decompose 400- codes here if you like
errorMessage =
string.Format("Error testing connection to web service at" +
" \"{0}\":\r\n{1}", url, ex);
Trace.TraceError(errorMessage);
if (throwExceptions)
throw new Exception(errorMessage, ex);
}
catch (Exception ex)
{
errorMessage =
string.Format("Error testing connection to web service at " +
"\"{0}\":\r\n{1}", url, ex);
Trace.TraceError(errorMessage);
if (throwExceptions)
throw new Exception(errorMessage, ex);
return false;
}
return true;
}