Click here to Skip to main content
15,867,594 members
Articles / Operating Systems / Windows
Article

Using a webservice to access data across multiple platforms

Rate me:
Please Sign up or sign in to vote.
2.83/5 (5 votes)
17 May 20077 min read 49.7K   204   27   10
This article is to demonstrate how a XML based webservice can be used to create an access tool to multiple datasources across multiple platforms

Introduction

Hi everyone.

The reason for this article is to explain how XML can be used in conjuction with .NET to create a platform where multiple platforms can integrate seamlessly.

A lot of people are sceptical of using web services, espicially when written in .NET but they forget that by exposing XML strings instead of .NET objects, a webservice can become one of the most powerful tools for a developer.

This article will show the basics of writing the webservice and show a schemtical view of integrating into a corporation.

This integration is based on Service Orientated Architecture(SOA).

Schematic View

First let's have a look at a schemtaic view of this solution:

Current Solution

As you can see in this picture, the solution entails multiple datasources on differant platforms and also multiple applications trying to access it. The next image will show you what my suggestion is for this solution.

The correct scheme

This solution looks more managable not only on images but also in coding. Even more important this saves time and money for all parties involved in this project.

Scenario

To make it interesting I will create a small scenario. This solution is for the CIA and they have two external systems. The Web based Intranet and a Highly secure facility in Langley. Now they have access levels where, depending on your authorization, you can either access certain sections of the building or the Intranet.

The webservice just connects to Datasource and checks if the user is authenticated. Return a Yea or Nay to them. The Intranet was built with PHP and JavaScript and the Access Card Reader Software with Unmanaged C++. Hope that tickles your fancy.

The Code

In this article I will only show you the code for the web service. In future articles I will explain the rest of this solution. But for now let's look at the web service.

What are the important things to remember? Well, we are writing this web service in C# .NET but it must be accessible across multiple languages so do not use .NET objects please! Stay away from returning say, datasets, as they will only integrate with .NET languages, which renders this whole document useless. Strings, integers and booleans are always safe to use but for me there is only one thing that will work. This is XML. So in my code you will see I expose a Web Method and return a string that is XML as well as accepting XML. OK, enough talk, let's look at the code.

[WebMethod] 
public string CheckUserAuthentication(string sXML)

First I exposed the web method and accepted a string input which should be a preformatted XML string. Security is better when going about this in my way as no one can really guess what the XML needs to look like.

This is what the input XML should look like:

/*input xml format:
* <xml>
* <userid>sUserID</userid>
* <authLevel>iAuthLevel</authLevel>
* </xml>*/

Error Handling

Since a lot of people will be accessing this service and they don't know what is happening we need to have a certain degree of Error Handling. Everyone has their own way of handling errors and I will explain mine first. I have three exposed properties called bError, sError and iErrorLevel which are Bool, string and integer respectively. As I go through my code I set the iErrorLevel to tell me where I am located within the code. The whole code section is in a try/catch block and once an error happens, I catch it, check the iErrorLevel integer, and know where the error occurred. Then I set the bError value to true and in the sError string I write an error message that tells the user what went wrong. On creating the return I check if there was an error and return the Error Message in the correct format to the user.

Whichever way you use is fine, this is just my way of doing this, back to the code.

We create the XML document object that we will use througout this function:

XmlDocument xmlDoc = new XmlDocument();

try
{
    //Set ErrorLevel

    iErrorLevel = 1;

In the following step we look at the XML Doc Obj that is loaded with the incoming XML and retrieve the UserID sent to us:

C#
XmlNode node1;
XmlNodeList nodelist;

node1 = xmlDoc.SelectSingleNode("xml/userid"); 
sUserID = node1.InnerText;
node1 = xmlDoc.SelectSingleNode("xml/authLevel");
iAuthLevelExternal = Convert.ToInt32(node1.InnerText);

//Throw exception if sUserID is not set
if ((sUserID == "") || (sUserID == null))
    throw new Exception();

Now we load our Datasource XML which is just a premade XML document I created. This can be any Datasource you like, or even multiple ones, whatever you wish.

string sPath = Server.MapPath("XML/UserData.xml"); 
xmlDoc.Load(sPath);

Now we loop though this XML document to find the correct user we are looking for, in this case UserID of JG001. Once we find the correct user we retrieve and set his allowed Authentication Level so we can compare it later:

C#
nodelist = xmlDoc.SelectNodes("xml/user");

//Set ErrorLevel
iErrorLevel = 4;

foreach (XmlNode node2 in nodelist)
{
    //Now we check to see if this is the user we are looking for
    if (node2.Attributes["UserID"].Value.ToString().ToLower() ==  
        sUserID.ToLower())
    {
        //This is the user we are looking for. Get the Authorization Level
        iAuthLevelDB = Convert.ToInt32(node2.ChildNodes[3].InnerText);
    }
}

Now that we have the user authentication level and the required authentication level we can compare the two. We subtract the Allowed Authentication Level and the Requested Authentication Level; the result will tell us if the user is authorised or not. We set the Bool bAuth to either true or false.

int iResult = iAuthLevelDB - iAuthLevelExternal;
if (iResult == 0)
{
    //Authorized
    bAuth = true;
}
else if (iResult > 0)
{
    //Authorized
    bAuth = true;
}
else if(iResult < 0 )
{
    //Unauthorized
    bAuth = false;
}
else
{
    //Could not verify
    bAuth = false;
    sError = "User could not be verified";
}

Now we have the answer to our question, is the user authenticated? Let the user know.

Remember that the return XML format must have the same layout even if an error occurs, or the user is not authenticated, etc. The user must handle the error on their side but the way they loop through our return XML must be in the same way every time otherwise their code will collapse. Have a look at the comments I left in my code regarding this.

Below you will see the Catch block for this function. It will explain what I do with my Error Handling. It checks to see what the integer value of iErrorLevel is and then it creates an error message. One of the advantages of this is if you need to change error messages they are all located in one central place ... quickly accessible!!

catch
{
    //Check the ErrorLevel to see what error happened
    switch (iErrorLevel)
{
case 1:
sError = "Invalid XML String supplied. Please check XML and try again";
break;

case 2:
sError = "User ID could not be located in supplied XML. Please check 
details.";
break;

case 3:
sError = "Internal XML Doc could not be loaded. Please contact Developer.";
break;

case 4:
sError = "Error occured while Accesing User information. Please contact 
Developer";
break;

case 5:
sError = "Error occured while Authenticating User. Please contact Developer";
break;
}
bError = true;
}

And the final step is to create the return XML. I check to see if the bError value is true or false and then create the XML return string. For values that will not be applicable I set it to -1. Never leave values unset as this will create a reference error in some code languages. So for stability sake, insert a -1. You will see the XML return string format is consistent no matter what the result.

Also notice that I return the recieved UserID as a means for the recipient to confirm that the right user was checked.

One last thing, the first childNode of the root XML node are the <error></error> tags. This will enable the recipient to check this first node to see if there was an error and then he can instantly handle the error on his code.

if (bError)
{
    //So there was a Error. Lets handle it!!
    sReturnXML += "<xml>";
    sReturnXML += "<error>1</error>";
    sReturnXML += "<errorMessage>" + sError + 
        "</errorMessage>";
    sReturnXML += "<userID>-1</userID>";
    sReturnXML += "<auth>-1</auth>";
    sReturnXML += "</xml>";

    //Notice we return -1 for values that is not set. This is just a way of 
    //returning a value but that is invalid
}

else
{
    //OK so user Authentication succeeded. Let create the XML
    sReturnXML += "<xml>";
    sReturnXML += "<error>0</error>";
    sReturnXML += "<errorMessage>-1</errorMessage>"; 
    sReturnXML += "<userID>" + sUserID +  
        "</userID>";

string sAuth;

if (bAuth)
{
    sAuth = "1";
}

else
{
    sAuth = "0";
}

sReturnXML += "<auth>" + sAuth + "</auth>";
sReturnXML += "</xml>";
}

And finally we just return the sReturnXML and that's it.

Conclusion

Now this web service can be consumed by any language and because it accepts XML and returns XML it integrates seamlessly!!

Now if there is a new application that has to be build the function is already there so for me there is no new work, and I control the structure of how people can access the Datasource. This increases security (sorry for those people that say web services are not secure).

And one more thing. I know a lot of people say this is only for large solutions, but you will be surprised at how many of your smaller websites can use this. Let's say wou have done 10 small websites in your life and all of them have a Country Select DropDownList somewhere. Imagine you can use a webservice to populate this dropdown everytime, no matter what language you are writing in? This could be a max five lines of codes to do all that everytime - there is potentially a lot of time and money saving hidden here!

In my next article I will talk more about accessing this service from various languages. If you have any questions let me know; I would love to find out what you think of my master plan to take over the world ... with a web service. Thank You.

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


Written By
Web Developer
South Africa South Africa
I have been programming for 5 years, and doing web and software design for 7 years. I worked for a blue chip company in the UK working with the web interface of Software Security.

Comments and Discussions

 
QuestionSceptic? Pin
Cormac M Redmond11-Jan-07 7:33
Cormac M Redmond11-Jan-07 7:33 
AnswerRe: Sceptic? Pin
Miela_SA11-Jan-07 20:42
Miela_SA11-Jan-07 20:42 
GeneralRe: Sceptic? Pin
Cormac M Redmond12-Jan-07 5:18
Cormac M Redmond12-Jan-07 5:18 
GeneralRe: Sceptic? Pin
Miela_SA14-Jan-07 20:02
Miela_SA14-Jan-07 20:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.