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).
First let's have a look at a schemtaic view of this 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.
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.
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.
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.
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:
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
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();
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:
node1 = xmlDoc.SelectSingleNode("xml/userid");
sUserID = node1.InnerText;
node1 = xmlDoc.SelectSingleNode("xml/authLevel");
iAuthLevelExternal = Convert.ToInt32(node1.InnerText);
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");
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:
nodelist = xmlDoc.SelectNodes("xml/user");
iErrorLevel = 4;
foreach (XmlNode node2 in nodelist)
if (node2.Attributes["UserID"].Value.ToString().ToLower() ==
iAuthLevelDB = Convert.ToInt32(node2.ChildNodes.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)
bAuth = true;
else if (iResult > 0)
bAuth = true;
else if(iResult < 0 )
bAuth = false;
//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!!
//Check the ErrorLevel to see what error happened
sError = "Invalid XML String supplied. Please check XML and try again";
sError = "User ID could not be located in supplied XML. Please check
sError = "Internal XML Doc could not be loaded. Please contact Developer.";
sError = "Error occured while Accesing User information. Please contact
sError = "Error occured while Authenticating User. Please contact Developer";
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.
//So there was a Error. Lets handle it!!
sReturnXML += "<xml>";
sReturnXML += "<error>1</error>";
sReturnXML += "<errorMessage>" + sError +
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
//OK so user Authentication succeeded. Let create the XML
sReturnXML += "<xml>";
sReturnXML += "<error>0</error>";
sReturnXML += "<errorMessage>-1</errorMessage>";
sReturnXML += "<userID>" + sUserID +
sAuth = "1";
sAuth = "0";
sReturnXML += "<auth>" + sAuth + "</auth>";
sReturnXML += "</xml>";
And finally we just return the
sReturnXML and that's it.
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.
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.