.Net, ASP.Net, C#, VB.net, SQL Server, Xml, CSS, Design Patterns related tips, tricks, code snippets, articles, links, thoughts, etc. from Binu & Subi Thayamkery.

Binu Thayamkery is a seasoned software architect with more than 13 years of experience in developing enterprise grade connected systems using Microsoft Technologies. In his current position as a lead consultant-solution architect with Prudential Financial, he is working on architecture of next generation investment reporting framework using .net 3.5/WCF/AJAX, etc. He holds a Masters Degree in Computer Science from Colorado State University. Subi Thayamkery is an experienced software developer with more than 8 years of developing various application software systems ranging from workflow automation systems to compliance management tools. She currently works as a technology consultant for Prudential Financial where she helps develop a new system for corportate governance department. She holds an Electrical Engineering degree from New Jersey Institute of Technology.

Wednesday, September 03, 2008

Welcome Google Chrome !

Yesterday I installed Google Chrome ! Google enters the browser market with "Chrome". After day 1 with Chrome, it impresses me. Nice and clean! Some of the interesting features include...
** Easy bookmarking
** More realesate
** Inbuilt search..type in address bar and go. Your default search engine results are displayed. There are some features that development community would love, for example,
** View source - clean layout with line numbers
** Javascript debugger and console, cool stuff, easy to trace your page layout !
** Task Manager - with some stats for the nerds ;)

Overall I would say...Nice Job!
Download Google Chrome from here

and did I say..there is a "incognito window" mode ?
Screenshot of Chrome


Cheers!

Monday, August 25, 2008

Understanding JSON

Here is a link where Javascript Object Notation (JSON) is explained well. Also, it has a good collection of related links.

Cheers!

Saturday, August 23, 2008

Simple Cascading Drop Down List using ASP.Net AJAX - Part 2


Earlier post we saw, how to do a simple cascaded dop down using ASP.Net AJAX. In this post we will modify that

code to use JSON to pass objects back from server side to client side. (Read more about JSON )here.)

Here
is the server side code (explanations inline),



public partial class _Default : System.Web.UI.Page

{

    
/* This is our entity object. IComparable implementation helps me to

     * sort the list of cars using its "Make" property. Also another point to note here is that

     * I have used "Automatic Properties" feature of C# 3.0 (More about new features of C# 3.0 in

     * a later post :)

     */

    class Car : IComparable<Car>

    {

        
public string Make { get; set; }

        
public string Model { get; set; }

        #region IComparable<Car> Members

        
int IComparable<Car>.CompareTo(Car other)

        {

            
return Make.CompareTo(other.Make);

        }

        #endregion

    }

    
/* This is the web method we will be calling from our javascript code. WebMethod attribute

     * makes it a web service method and ScriptMethod makes it visible to Javascript

     */

    [System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]

    
public static string GetModelsJSON(string key)

    {

        
/* Next couple of calls are basic setup of data for this, MakeList() creates a list of

         * Car objects, SearchModel will get a subset of that list using the key passed from

         * client script

         */

        List<Car> cars = MakeList();

        List<Car> selected = SearchModel(cars, key);

        
/* Now we create a JSON string that will be sent back to calling JavaScript code.

         * Read more on JSON Specification => http://www.json.org/

         */

        StringBuilder sb = new StringBuilder();

        sb.Append(
"{\"Models\":[");

        
foreach (Car car in selected)

        {

            PropertyInfo[] properties = car.GetType().GetProperties();

            sb.Append (
"{");

            
foreach (PropertyInfo p in properties)

            {

                sb.Append(
"\""+p.Name+"\"");

                sb.Append(
":");

                sb.Append(
"\""+p.GetValue(car, null)+"\"");

                sb.Append(
",");

            }

            sb.Remove(sb.Length - 1,1);

            sb.Append (
"},");

        }

        sb.Remove(sb.Length - 1,1);

        sb.Append(
"]}");

        
return (sb.ToString());

    }

    
/* Methods I was mentioning earlier on...Search for cars

     * This method uses an anonnymous method to delegate FindAll

     */

    private static List<Car> SearchModel(List<Car> cars, string key)

    {

        cars.Sort();

        List<Car> selectedCars =

          cars.FindAll(

          
delegate(Car car)

          {

              
return (car.Make == key);

          });

        
return (selectedCars);

    }

    
private static List<Car> MakeList()

    {

        List<Car> cars =
new List<Car>();

        Car car =
new Car();

        car.Make =
"BMW";

        car.Model =
"330 i";

        cars.Add(car);

        
/* Add more cars */

        return (cars);

    }

    
/* Set up drop down lists on Page_Load

     */


    
protected void Page_Load(object sender, EventArgs e)

    {

        
if (!IsPostBack)

        {

            
//Populate "One"

            One.Items.Add(new ListItem("BMW", "BMW"));

            One.Items.Add(
new ListItem("Audi", "Audi"));

            One.Items.Add(
new ListItem("Honda", "Honda"));

            One.Items.Add(
new ListItem("Pick One", ""));

            One.Items[3].Selected =
true;

            Two.Items.Add(
new ListItem("Pick One", ""));



            
//add attribute for "One"

            One.Attributes.Add("onchange", "return getModels();");



        }

    }

}



Once
this much is done, server side code is complete. Run it at this point.

You will get a client script error when you change the first drop down list..

Adding Javascript code will take care of that... getModels() method
is called

each time when you pick a
new item from the list. This method calls the web method

and result returned
is an JSON string. You can use eval('(' + result + ')') or

Sys.Serialization.JavaScriptSerializer.deserialize(result,
true); to invoke Javacript

compiler to convert JSON
string to object.



Here
is my code for aspx page...

   <div>

        <asp:ScriptManager ID=
"sm" runat="server" EnablePageMethods="true" >

        </asp:ScriptManager>

        <script language=
"javascript" type="text/javascript" >

        
//This is the mehod called from first drop downs "onchange" event

        function getModels()

        {

            var makelist = document.getElementById(
"One");

            
// get selected car make from dropdown list

            var key = makelist.options[makelist.selectedIndex].value;

            
// call the method on the server and wait till the code

            // has completed its execution.

            PageMethods.GetModelsJSON(key,OnGetModelsComplete);

        }

        function OnGetModelsComplete(result)

        {  

            
try

            {

                var o = Sys.Serialization.JavaScriptSerializer.deserialize(result,
true);

                PopulateModels(o)

            }
catch(e){}

        }

        function PopulateModels(o)

        {

            var models = document.getElementById(
"Two");

            
for (var count=models.options.length-1;count > -1; count--)

                models.options[count] =
null;



            var idValue;

            var textValue;

            var optionItem;

            
for(i = 0; i < o.Models.length;i++)

            {

                textValue = o.Models[i].Model;

                idValue = o.Models[i].Make;

                optionItem =
new Option( textValue, idValue,  false, false);

                models.options[i] = optionItem;

            }

        }

        </script>

        <asp:DropDownList ID=
"One" runat="server">

        </asp:DropDownList><br />

        <asp:DropDownList ID=
"Two" runat="server">

        </asp:DropDownList>

    </div>






Thursday, August 21, 2008

Update to post: HOWTO: Get rid of " Could Not Establish Trust Relationship with Remote Server" error

Read original post here.
Older methods are now obselete. Use the following...

...
...
System.Net.ServicePointManager.ServerCertificateValidationCallback
+= new System.Net.Security.RemoteCertificateValidationCallback(RemoteCertValidateCallback);
...

and callback method...


public static bool RemoteCertValidateCallback(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)

{

    
return true;

}





or you can simply use (in c# only) anonnymous method,


System.Net.ServicePointManager.ServerCertificateValidationCallback

    +=
delegate

            (

            
object sender,

            
X509Certificate cert,

            
X509Chain chain,

            System.Net.Security.
SslPolicyErrors error

            )

{
return (true); };

Tuesday, July 29, 2008

Visual Studio 2008 Web Deployment Projects

Download it from here.

Best feature you can get from this, "Create a single assembly" for all your files in your web project. It also offers a lot more customisation for MSBuild. For me, creation of single assembly for all the files became so important because of library management issues.

Scott Guthrie has couple of nice blog entries on this read it here
and here.



Cheers

Friday, July 25, 2008

Simple Cascading Drop Down List using ASP.Net AJAX

Here is a step by step tutorial to create a simple cascading drop down list,

1) Add a new asp.bet (aspx) page and 2 drop down controls into it.



<asp:DropDownList ID="One" runat="server">

</asp:DropDownList><br />



<asp:DropDownList ID="Two" runat="server">

</asp:DropDownList>


2) Add some server side code to populate the first drop down, depending on selection on first drop down we will populate the second one. (well thats the idea :)




    protected void Page_Load(object sender, EventArgs e)

    {

        
if (!IsPostBack)

        {

            
//Populate "One"

            One.Items.Add(new ListItem("BMW", "BMW"));

            One.Items.Add(
new ListItem("Audi", "Audi"));

            One.Items.Add(
new ListItem("Honda", "Honda"));

            One.Items.Add(
new ListItem("Pick One", ""));

            One.Items[3].Selected =
true;

            Two.Items.Add(
new ListItem("Pick One", ""));



            
//add attribute for "One"

            One.Attributes.Add("onchange", "return getModels();");



        }

    }



3) ok, at this point, its worth running your project and see whether controls display propery with the first list showing makes of the cars and second one showing the default item.

4) Switch back to aspx code, and add a scriptmanager control to it (this is the heart of asp.net ajax... read more here.. Make sure that EnablePageMethods is set to true. This will enable us to call server side page methods from Javascript.





<asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true" >

</asp:ScriptManager>


5) Now we are ready to write some javascript code, you might have noticed (and you got a script error possibly when you ran your project the first time) that we have added "onchange" event attribute to our first drop down list. Now we will write some javascript code to handle it. What we will do is to call the server side method to get the second drop down's values and populate the control with it.

When we call server side method, we use PageMethods. format. Here is how our server side method will look like,




[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]

public static string GetModels(string key)

{

    
if (key == "BMW")

    {

        
return ("330 i|330 xi|530 i|530 xi|750 i|X5|X3");

    }

    
if (key == "Audi")

    {

        
return ("A4|A4 Turbo|A6 Quattro|A8 Q");

    }

    
if (key == "Honda")

    {

        
return ("Civic EX|Accord EX-L|Accord EX-LV6|Pilot EX");

    }

    
return ("");

    

}



Simple isn't it? Notice the attributes set on the method. These attributes will enable it to be accessible from the Javascript side. So back to Javascript now...below given code shows it all...




<script language="javascript" type="text/javascript" >

//This is the mehod called from first drop downs "onchange" event

function getModels()

{



    
var makelist = document.getElementById("One");

    
// get selected car make from dropdown list

    var key = makelist.options[makelist.selectedIndex].value;

    
// call the method on the server and wait till the code

    // has completed its execution.

    PageMethods.GetModels(key,OnGetModelsComplete);

}

function OnGetModelsComplete(result)

{  

    
//you get the related models of car here!

    //use it to populate the drop down

    PopulateModels(result);

}

function PopulateModels(result)

{

    
var models = document.getElementById("Two");

    
for (var count=models.options.length-1;count > -1; count--)

    {    

        models.options[count] =
null;

    }

    
var items = result.split('|');

    

    
var idValue;

    
var textValue;

    
var optionItem;

    
for(i = 0; i < items.length;i++)

    {

        textValue = items[i];

        idValue = items[i];

        optionItem =
new Option( textValue, idValue,  false, false);

        models.options[i] = optionItem;

    }

}

</script>






The out-of-band call on PageMethods.... takes the first parameter as the input to the function and the second parameter the callback function name. This function will be calledback when the response gets back from the server...and rest is
all simple as taking the result and doing what ever you want with it..in this case build second drop down list option values...

Cheers!

Wednesday, July 16, 2008

Sql Server TRY-CATCH

A nice new feature in Sql Server 2005 is exception handling with TRY-CATCH, you can read all about it here -> MSDN Link

Friday, June 13, 2008

Inserting/Updating Rows in Sql Database - Avoid chatty interface

Its a good design practise to avoid chatty interfaces. This is not only true when we design our objects and interactions among objects, but also for your database interactions. For example if you have multiple rows to be updated to your table, its highly inefficient to fire your inserts one at a time to your database. If you are using a dataset, in ADO.net 1.1, data adapters update method prcessed each datarow one at a time. In ADO.Net 2.0, there is a new property for the adapter alled "UpdateBatchSize" by which you can control how many rows are send as a batch. To read more about this click on this MSDN link


But how about you have a list of your custom objects you want to use to do your inserts, in this case you can use the power of Xml processing in Sql Server, trick is to format your request as an Xml string and send it once to your database stored proc. This stored proc will process this Xml string and it updates/inserts your rows.


To demonstrate this lets, say you want to insert rows into your Employee Table, represented by Employee (ID,Name)


From your .net code, you will format an Xml request string similar to this,



< EmployeeList >
< Employee ID="E001" Name="John Doe" / >
< Employee ID="E002" Name="Mary Smith" / >
< Employee ID="E003" Name="Luke Skywalker" / >
</ EmployeeList >



and here is how your stored procedure will look like,



CREATE PROCEDURE [dbo].[sp_SaveRows]
(
@request ntext
)
AS
Begin
DECLARE @idoc int
EXEC sp_xml_preparedocument @idoc OUTPUT, @request

Declare @Id nvarchar(10)
Declare @Name nvarchar(255

DECLARE curs CURSOR FOR
SELECT Id, Name
FROM OPENXML (@idoc, '/savelist//saveitem',2)
WITH (
[Id] nvarchar(10) '@Id',
[Name] nvarchar(255) '@Name',
)
OPEN curs
FETCH NEXT FROM curs INTO @Id,@Name
WHILE @@FETCH_STATUS = 0
BEGIN

-- Do your insert/update here!

FETCH NEXT FROM curs INTO @Id,@Name
END
CLOSE curs
DEALLOCATE curs

End



As you can see, we use OPENXML call to read the Xml file and use it in cursor, if you do not want to use a cursor you can always directly insert into table using the select (with openxml). Use cursor if you want to do any kind of data manipulation or rule checking, calculations, etc...


Cheers!

Wednesday, June 04, 2008

AJAX Control Toolkit - Collapse Panel Flicker

If your collapse panel is causing your page to flicker while panels are collapsed and expanded, make sure that "SuppressAutoPostback" property is set to false. (Why would anyone wants to postback on panel actions anyways ??!!)

In many forums I have seen setting style="overflow:hidden" Height="0" for panel as a solutions, for me suppressing postback did the trick...

Cheers!

Friday, May 02, 2008

ASP.Net AJAX - Growing Pain !

I have a project where I use AJAX Extensions Ver 1.0, I am using Visual Studio 2008 and my target .Net Framework Ver is 3.0, All of a sudden I started getting this error!


The type 'System.Web.UI.UpdatePanel' exists in both 'c:\WINDOWS\assembly\GAC_MSIL\System.Web.Extensions\3.5.0.0__31bf3856ad364e35\System.Web.Extensions.dll' and 'c:\WINDOWS\assembly\GAC_MSIL\System.Web.Extensions\1.0.61025.0__31bf3856ad364e35\System.Web.Extensions.dll'

Googling the error, got pointers to look at "References" and "Web.config" to ensure that there is no reference to System.Web.Extensions ver 3.5, did that .... and much more... drove me nuts for a good couple of hours.

And at last found this in one of my test pages !!!


<%@ Register assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral,

PublicKeyToken=31bf3856ad364e35"
namespace="System.Web.UI.WebControls" tagprefix="asp" %>



Removing this page directive made all the difference, project started compiling fine again...
and I can have a peaceful weekend !

Cheers!

Friday, April 25, 2008

Creating Schema from Xml file

Here is a code snippet that creates a simple schema file from an
Xml file. It uses XmlSchemaInference class (available from .net 2.0+)
to inferschema from an xml file.


        XmlReader reader = XmlReader.Create(@"c:\binu\customer.xml");

        
XmlSchemaSet schemaSet = new XmlSchemaSet();

        
XmlSchemaInference schema = new XmlSchemaInference();



        schemaSet = schema.InferSchema(reader);

        
TextWriter writer = new StreamWriter(@"c:\binu\customer.xsd");

        
foreach (XmlSchema s in schemaSet.Schemas())

        {

            s.Write(writer);

        }




Sample Xml file used:


<Customers>

<
Customer CustomerName="Maria Anders" Country="Germany"/>

<
Customer CustomerName="Ana Trujillo" Country="Russia"/>

<
Customer CustomerName="Antonio Moreno" Country="Spain"/>

<
Customer CustomerName="Thomas Hardy" Country="United Kingdom"/>

<
Customer CustomerName="Maria Anders" Country="Holand"/>

<
Customer CustomerName="Christina Berglund" Country="Sweden"/>

</
Customers>




Output:


<?xml version="1.0" encoding="utf-8"?>

<
xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <
xs:element name="Customers">

    <
xs:complexType>

      <
xs:sequence>

        <
xs:element maxOccurs="unbounded" name="Customer">

          <
xs:complexType>

            <
xs:attribute name="CustomerName" type="xs:string" use="required" />

            <
xs:attribute name="Country" type="xs:string" use="required" />

          </
xs:complexType>

        </
xs:element>

      </
xs:sequence>

    </
xs:complexType>

  </
xs:element>

</
xs:schema>


Happy coding!
Cheers!

Tuesday, April 22, 2008

Framework 3.5/VS 2008 web.config

If you are new to Visual Studio 2008 (Framework 3.5), first thing you will notice is that there are lot of new stuff in the web.config file by default.
I found a useful article from 4GuysFromRolla on this, check it out !
Link to article

Cheers

ASP.Net-Crystal Reports Application Deployment

If you are trying to deploy ASP.Net/Crystal Application (I was using VS 2008) and
got errors while running your app, here is something to look for;

1) If you are getting errors, saying "failed to load" some Crystal Assemblies, reasonmight be that you do not have the right Crystal Run time installed in your server.
Crystal Runtime comes with Visual Studio 2008, and you can locate that in the machine
you have installed VS 2008. Path is C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\CrystalReports10_5\CRRedist2008_x86.msi

If you have Visual Studio 2005, you can find the runtime installer in
C:\Program Files\Microsoft Visual Studio 8\Crystal Reports\CRRedist\X64\CRRedist2005_X64.msi

2) Once you have successfully installed runtime and run your application, if you get an error saying "load report failed"...permissions are usually the culprit. Give IIS_WPG group read-write permissions on TEMP directory on your server (check your environment settigs to see where your TEMP is defined)
This is true even if you are impersonating an id to run your application and not using Network Service/ASPNET accounts to run.


Cheers

Friday, February 15, 2008

ASP.Net v1.1 and v2.0 side by side

Its common knowledge that we can run ASP.Net v1.1 and v2.0 side by side. If both the versions of .Net frameworks are installed on the server, IIS management console will provide a new ASP.Net tab in the property page (right click on your IIS application/vdir, select properties). Here you can select which version of ASP.Net you want to target.

If you are moving from v1.1 up, it is highly probable that you will have some applications still using older versions of .Net, in that case your new application in the same server will need to be configrued for ASP.Net 2.0. Even after you run if you get an error saying "Server application not available", check to see whether new application is running under the same application pool as older ones. By default, it will be using DefaultApplication Pool. Create a new application pool and assign this pool for your new ASP.Net 2.0 application.

Cheers!

Thursday, January 10, 2008

Visual Studio 2008 and VSS 2005

Installed Visual Studio.Net 2008 Team System today. First thing noticed was VSS integration was not there. I use VSS 2005 for source control not Team Foundation Server(TFS). It didn't take much time on google to find an update for VSS 2005 and a useful blog entry in Richard Berg's Blog.
Once you apply the VSS update from this link you are all set to use VS.Net 2008 with VSS. (This update fixes a whole bunch of VSS issues as listed here.)

(Make sure that in Visual Sudio 2008, Tools > Options - Source Control, Microsoft Visual Sourcesafe is selected as current source control plug-in)

Cheers!

Welcome 2008!

Welcome 2008!
We hope New Year brings new hope and cheer in everyone’s life.
We are glad to announce that we are back to blogging our .Net life. We had taken a nice long break from all these and now back to explore more in .Net world.

Cheers!