Showing posts with label Web Services. Show all posts
Showing posts with label Web Services. Show all posts

Wednesday, July 8, 2009

Dynamic Menu using Flex

I think it is time now to share some of the initial work I have done in Flex which served as a part of my learning process as well.

A dynamic menu - fully populated from data stored in MS SQL - fed via a web service.
It is important to mention that most of the functionality was pretty much handled in the web service (IMO, that is how it should be).

The only thing I learnt in flex through this project was to use the Menu control and to perform a simple WS call.

The database has a table 'tbl_menu' that stores all the menu details. It references itself via the field ParentMenu_id for sub menus.



The only input the Flex page needs is a cleanly formatted xml string. So that is what the WS is going to return:


[WebMethod]
public string GetMenuByClass(String usrclass)
{
StringBuilder sb = new StringBuilder();

Dictionary> dict = new Dictionary>();
dict = GetMenuDict(usrclass);

sb.Append("");
sb.Append("");
foreach (int key in dict.Keys)
{
sb.Append(AddXmlString(dict[key]));
}
sb.Append("
");

return sb.ToString();
}


It is just a plain method that uses StringBuilder to append the xml string. There are a hundred different ways to construct the xml, but that is not part of this sample.

Also you would notice soon that we are using a simple object class 'MenuInfo' that represents the actual DB entity which will be used that to pass around data.

Next, the GetMenuDict function takes care of populating a dictionary with all the menu data it pulled from the DB:


private Dictionary> GetMenuDict(string userAccessCode)
{
Dictionary> dict = new Dictionary>();

List menuItems = new List();

menuItems = GetMenuFromDB(userAccessCode);

foreach (MenuInfo m in menuItems)
{
// root element - 0 or NULL
if (m.Parent_Link_id == 0)
{
if (dict.ContainsKey(m.Parent_Link_id))
{
dict[m.Parent_Link_id].Add(m);
}
else
{
List lst = new List();
lst.Add(m);
dict.Add(m.Parent_Link_id, lst);
}
}
else
{
// not a root element - parent exists. find it and add this guy to his list
MenuInfo mInfo = null;

foreach (int key in dict.Keys)
{
mInfo = FindMenuInfoRecursive(m.Parent_Link_id, dict[key]);
if (mInfo != null)
{
mInfo.menuList.Add(m);
}
}
}
}

return dict;
}


The GetmenuFromDB just reads the data from the Database using a datareader and returns a list of MenuInfo. The more inportant function is the FindMenuInfoRecursive, which takes care of handling the sub menus. With this method the sample supports infinite level of sub listing menu items, by just setting the appropriate ParentMenu_id.


private MenuInfo FindMenuInfoRecursive(int id, List menuList)
{
MenuInfo menu = null;

foreach (MenuInfo item in menuList)
{
if (item.Menu_id == id)
{
menu = item;
break;
}
else
{
menu = FindMenuInfoRecursive(id, item.menuList);
if (menu != null)
{
break;
}
else
{
continue;
}
}
}

//finally return the menu object
return menu;
}


The AddXmlString is the method we are going to see next:


private string AddXmlString(List menuList)
{
StringBuilder sb = new StringBuilder();

foreach (MenuInfo m in menuList)
{
if (m.menuList.Count > 0)
{
//should continue
sb.Append(String.Format("", m.Name, m.Name));
sb.Append(AddXmlString(m.menuList));
sb.Append(String.Format("
", m.Name, m.Name));
}
else
{
sb.Append(String.Format("", m.Name, m.Name));
}
}
return sb.ToString();
}


With all this done at the WS, it leaves us with very little to do at the Flex end. We would just be making the call to the WS and merely bind the results.


public function WSMenuSvcResultHandler(event:ResultEvent):void{
var dataXML:XML = new XML();
dataXML = XML(event.result.toString());

var myMenu:Menu = Menu.createMenu(null, dataXML, false);
myMenu.labelField="@label";
myMenu.show(10, 20);
}


The full C# source for this example is here and the Flex source is here.

Sunday, May 10, 2009

Web Services: Code-First vs Contract-First approach

One of my colleagues who recently moved to work in a maintenance project based on Java, came back to discuss about the Web Service pattern followed there. He used terms like ‘Top-Down’ and ‘Bottom-Up’ approach and mentioned that so many different things were possible in the Java world.

Curious to find out more on what he exactly meant and also in a secret desire to defend .Net, I explored based on the details he gave.

1. Parameters passed to the web method can be validated based on a limit/range.
a. Ex. Value passed in for an integer parameter can be checked if the value is within a defined range or format. Or a date parameter can have a range specified
2. The Web service code was generated from a defined WSDL and not the usual other way around.

Below are my findings:
There are two approaches to build a web service: Code First approach and Contract First approach.

1. Code First approach – where you write the web methods and then add a web reference of this service in whatever client you are using. If it is a .Net client, it will generate a wsdl file and a reference.vb (or .cs) to define the types and methods used/defined in the service.

2. Contract First Approach – you start working on building the WSDL file first. Define and write your types and methods in the WSDL. The code is generated from this WSDL (.Net provides the option through the wsdl.exe tool).

Which approach to choose, purely depends upon the requirement. The contract first approach is surely the only option when you are leaning on interoperability. If your web service is just going to be consumed internally by your own applications (like how I have been using it all along), then the code first approach should be totally fine.

The contract first approach is tedious and could easily get messy if you are not sure of what you are doing. Also it requires a person to have a very good understanding of the schema design and should be able to fluently code. But then there are quite a few schema designer tools available. But by modifying the schema, you can perform restrictions on the parameters and can even perform schema validations.

One solution that is very popular is Thinktecture Contract First. They provide you with a nice option where it integrates smoothly into the Visual Studio IDE and makes the code generation out of a schema file pretty simple and easy. Also among the many other options, they have encapsulated the Web Service custom validation of SOAP requests against the definitions defined within the source WSDL file using Attributes.

I shared these findings with my colleague and made him realize that what he had seen in his new project is not something related specifically to Java.

References:
http://www.frotscher.com/download/JUG-ContractFirst.pdf
http://ftp.mcs.anl.gov/pub/tech_reports/reports/P1319.pdf