Jun
19
2007
Simple ASP.NET SOA architecture
Posted by admin under
ASP.NET 2.0

Overview
Here we will create a ASP.NET driven application providing a domainname to ip service for a Windows client application.
Foreword
Ok, here I will get into a "hot" concept - SOA - but to be honest - I don't care about the names and terminology - I just wanted a soluton that performed ok. However - do be correct - I do care about the names, domain names. Cause that what it was all about. I needed to batch lookup the ip addresses of a LOT of domain names. The reason was to generate some test input for admentor.net IP to country lookup tool, so I simply needed a lot of IP addresses.
The client
So easy, right. Consider a windows forms app where textBox1 contains one domain name for each row:
System.Text.StringBuilder oRet = new StringBuilder();
foreach (string sOneDomainname in textBox1.Text.Split('\n'))
{
string sOneName = sOneDomainname.Replace("\r", "").Trim();
//get IP
System.Net.IPHostEntry he = System.Net.Dns.GetHostEntry(sOneName);
if (he.AddressList.Length > 0)
{
oRet.Append(sOneName + ":" + he.AddressList[0].ToString() + Environment.NewLine);
}
}
The problem
However, with a list of a couple of thousand domain names it took ages. A single call to get IP addresses for a domain name can't be noticable as slow, I mean the difference between 1ms or 2ms, but when batching thousands of calls together it all added up.
The solution
So, now, I thought - let's create a ASP.NET application on one of my web servers - they are connected to Internet with fiber 100MB so each single call should be a lot faster.
Now - the design issues. If I did it the very right way I would of course create a real webservice for this. I might update the project later to do just that, but I chose to implement it as single ASP.NET page. Important is for it to allow input of a batchload of names. Cause what we are looking for is a single call from my laptop to the server, the server makes all the calls - and return the result (batchwise) back to the laptop.
So, I chose a really simple REST interface, having the client just POST data (each domainname on a single row) to the webserver. http://www.theserverblabla.com/dnsllokup/dolookup.aspx

When clicking on Run web we build up a string with one domainname on each row
private void button2_Click(object sender, EventArgs e)
{
System.DateTime dtStart = DateTime.Now;
string sUrl = "http://localhost:3508/dnslookup.aspx";
System.Text.StringBuilder oRet = new StringBuilder();
foreach (string sOneDomainname in textBox1.Text.Split('\n'))
{
string sOneName = sOneDomainname.Replace("\r", "").Trim();
oRet.Append(sOneName + Environment.NewLine);
}
string sRet = PostDomainDataToServer(sUrl, oRet.ToString());
System.DateTime dtEnd = DateTime.Now;
TimeSpan oSpan = dtEnd - dtStart;
label4.Text = oSpan.TotalMilliseconds.ToString() + " ms";
textBox2.Text = sRet;
}
The PostDomainDataToServer creates a webclient object posting the data
public static string PostDomainDataToServer(string url, string sPostData)
{
string sRet = "ERROR";
System.Net.WebClient oCli = null;
try
{
System.Collections.Specialized.NameValueCollection mValues = new System.Collections.Specialized.NameValueCollection();
mValues.Add("domainnames", sPostData);
oCli = new System.Net.WebClient();
byte[] bData = oCli.UploadValues(url,mValues);
sRet = Encoding.UTF8.GetString(bData);
return sRet;
}
catch (System.Net.WebException ex)
{
//Console.Write(ex.Message);
}
if (oCli != null)
{
oCli.Dispose();
oCli = null;
}
return sRet;
}
As you can see we post the data as field "domainnames" which lets us use Request["domainname"] on the server (file domainlookup.aspx):
protected void Page_Load(object sender, EventArgs e)
{
System.Text.StringBuilder oRet = new System.Text.StringBuilder();
//Check for data...
foreach (string sOneDomainname in Request["domainnames"].Split('\n'))
{
string sOneName = sOneDomainname.Replace("\r", "").Trim();
//get IP
System.Net.IPHostEntry he = System.Net.Dns.GetHostEntry(sOneName);
if (he.AddressList.Length > 0)
{
oRet.Append(sOneName + ":" + he.AddressList[0].ToString() + Environment.NewLine);
}
}
Response.Clear();
Response.ContentType = "text/plain";
Response.Write( oRet.ToString());
Response.End();
}
Of course - for small amount of data if won't be any notice - well actually the service road will
be a lot slower. But with large amount of data it sure got a lot faster for me. Also - now
I do have a general service which I can reuse in other projects, maybe...Well this stupiod case might
not be reused, I admit, but you get the idea.
Feel free to download the sample (Visual Studio 2005 solution, C#).
Ending it all up
Of course - for small amount of data if won't be any notice - well actually the service road will be a lot slower. But with large amount of data it sure got a lot faster for me. Also - now
I do have a general service which I can reuse in other projects, maybe...Well this stupiod case might not be reused, I admit, but you get the idea.
Feel free to download the sample (Visual Studio 2005 solution, C#).
It contains two projects - when testing from within Visual Studio then
the ASP.NET project (DNSLookup) is what you should run. Then when DNSLookup is running, rightclick on DNSSOa (windows form project), Debug, Start new instance. Now both are running.
You also need to change the string sUrl = "http://localhost:3508/dnslookup.aspx"; to
whatever port it's using on your local box.
Attachments