<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8769773808837040573</id><updated>2011-11-27T15:50:59.995-08:00</updated><title type='text'>.Net C# SqlServer Javascript Ajax! Thats something abt me!</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-2593455790802422106</id><published>2010-02-26T21:03:00.000-08:00</published><updated>2010-02-26T21:07:55.124-08:00</updated><title type='text'>Cursors in Sql server-Basics</title><content type='html'>We'll talk about the basics of cursors. These let you move through rows one at a time and perform processing on each row. (This article has been updated through SQL Server 2005.)&lt;br /&gt;&lt;br /&gt;SQL Server is very good at handling sets of data. For example, you can use a single UPDATE statement to update many rows of data. There are times when you want to loop through a series of rows a perform processing for each row. In this case you can use a cursor.&lt;br /&gt;&lt;br /&gt;    Please note that cursors are the SLOWEST way to access data inside SQL Server. The should only be used when you truly need to access one row at a time. The only reason I can think of for that is to call a stored procedure on each row.  In the Cursor Performance article I discovered that cursors are over thirty times slower than set based alternatives.&lt;br /&gt;&lt;br /&gt;The basic syntax of a cursor is:&lt;br /&gt;&lt;br /&gt;DECLARE @AuthorID char(11)&lt;br /&gt; &lt;br /&gt;DECLARE c1 CURSOR READ_ONLY&lt;br /&gt;FOR&lt;br /&gt;SELECT au_id&lt;br /&gt;FROM authors&lt;br /&gt;&lt;br /&gt;OPEN c1&lt;br /&gt;&lt;br /&gt;FETCH NEXT FROM c1&lt;br /&gt;INTO @AuthorID&lt;br /&gt;&lt;br /&gt;WHILE @@FETCH_STATUS = 0&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt; PRINT @AuthorID&lt;br /&gt;&lt;br /&gt; FETCH NEXT FROM c1&lt;br /&gt; INTO @AuthorID&lt;br /&gt;&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;CLOSE c1&lt;br /&gt;DEALLOCATE c1&lt;br /&gt;&lt;br /&gt;The DECLARE CURSOR statement defines the SELECT statement that forms the basis of the cursor. You can do just about anything here that you can do in a SELECT statement. The OPEN statement statement executes the SELECT statement and populates the result set. The FETCH statement returns a row from the result set into the variable. You can select multiple columns and return them into multiple variables. The variable @@FETCH_STATUS is used to determine if there are any more rows. It will contain 0 as long as there are more rows. We use a WHILE loop to move through each row of the result set.&lt;br /&gt;&lt;br /&gt;The READ_ONLY clause is important in the code sample above.  That dramatically improves the performance of the cursor.&lt;br /&gt;&lt;br /&gt;In this example, I just print the contents of the variable. You can execute any type of statement you wish here. In a recent script I wrote I used a cursor to move through the rows in a table and call a stored procedure for each row passing it the primary key. Given that cursors are not very fast and calling a stored procedure for each row in a table is also very slow, my script was a resource hog. However, the stored procedure I was calling was written by the software vendor and was a very easy solution to my problem. In this case, I might have something like this:&lt;br /&gt;&lt;br /&gt;EXEC spUpdateAuthor (@AuthorID)&lt;br /&gt;&lt;br /&gt;instead of my Print statement. The CLOSE statement releases the row set and the DEALLOCATE statement releases the resources associated with a cursor.&lt;br /&gt;&lt;br /&gt;If you are going to update the rows as you go through them, you can use the UPDATE clause when you declare a cursor. You'll also have to remove the READ_ONLY clause from above.&lt;br /&gt;&lt;br /&gt;DECLARE c1 CURSOR FOR&lt;br /&gt;SELECT au_id, au_lname&lt;br /&gt;FROM authors&lt;br /&gt;FOR UPDATE OF au_lname&lt;br /&gt;&lt;br /&gt;You can code your UPDATE statement to update the current row in the cursor like this&lt;br /&gt;&lt;br /&gt;UPDATE authors&lt;br /&gt;SET au_lname = UPPER(Smith)&lt;br /&gt;WHERE CURRENT OF c1&lt;br /&gt;&lt;br /&gt;That covers the basics of cursors&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-2593455790802422106?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/2593455790802422106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/cursors-in-sql-server-basics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/2593455790802422106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/2593455790802422106'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/cursors-in-sql-server-basics.html' title='Cursors in Sql server-Basics'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-5530645299187214552</id><published>2010-02-26T21:00:00.000-08:00</published><updated>2010-02-26T21:03:56.130-08:00</updated><title type='text'>Export Gridview data to an Excel sheet</title><content type='html'>protected void imgExport_Click(object sender, ImageClickEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        PrepareGridViewForExport(gvAttendance);&lt;br /&gt;        string attachment = "attachment; filename=CounsellingDetails.xls ";&lt;br /&gt;        Response.ClearContent();&lt;br /&gt;        Response.AddHeader("content-disposition", attachment);&lt;br /&gt;        Response.ContentType = "application/ms-excel";&lt;br /&gt;        StringWriter sw = new StringWriter();&lt;br /&gt;        HtmlTextWriter htw = new HtmlTextWriter(sw);&lt;br /&gt;        //GridView gv = new GridView();&lt;br /&gt;        //gv.DataSource = GetResults();&lt;br /&gt;        //gv.DataBind();&lt;br /&gt;        gvAttendance.RenderControl(htw);&lt;br /&gt;        Response.Write(sw.ToString());&lt;br /&gt;        Response.End();&lt;br /&gt;    }&lt;br /&gt;    public override void VerifyRenderingInServerForm(Control control)&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;    private void PrepareGridViewForExport(Control gv)&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        LinkButton lb = new LinkButton();&lt;br /&gt;&lt;br /&gt;        Literal l = new Literal();&lt;br /&gt;&lt;br /&gt;        string name = String.Empty;&lt;br /&gt;&lt;br /&gt;        for (int i = 0; i &lt; gv.Controls.Count; i++)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            if (gv.Controls[i].GetType() == typeof(LinkButton))&lt;br /&gt;            {&lt;br /&gt;&lt;br /&gt;                l.Text = (gv.Controls[i] as LinkButton).Text;&lt;br /&gt;&lt;br /&gt;                gv.Controls.Remove(gv.Controls[i]);&lt;br /&gt;&lt;br /&gt;                gv.Controls.AddAt(i, l);&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            else if (gv.Controls[i].GetType() == typeof(DropDownList))&lt;br /&gt;            {&lt;br /&gt;&lt;br /&gt;                l.Text = (gv.Controls[i] as DropDownList).SelectedItem.Text;&lt;br /&gt;&lt;br /&gt;                gv.Controls.Remove(gv.Controls[i]);&lt;br /&gt;&lt;br /&gt;                gv.Controls.AddAt(i, l);&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            else if (gv.Controls[i].GetType() == typeof(CheckBox))&lt;br /&gt;            {&lt;br /&gt;&lt;br /&gt;                l.Text = (gv.Controls[i] as CheckBox).Checked ? "True" : "False";&lt;br /&gt;&lt;br /&gt;                gv.Controls.Remove(gv.Controls[i]);&lt;br /&gt;&lt;br /&gt;                gv.Controls.AddAt(i, l);&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if (gv.Controls[i].HasControls())&lt;br /&gt;            {&lt;br /&gt;&lt;br /&gt;                PrepareGridViewForExport(gv.Controls[i]);&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-5530645299187214552?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/5530645299187214552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/export-gridview-data-to-excel-sheet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5530645299187214552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5530645299187214552'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/export-gridview-data-to-excel-sheet.html' title='Export Gridview data to an Excel sheet'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-2574067201532195638</id><published>2010-02-26T20:56:00.000-08:00</published><updated>2010-02-26T21:00:21.367-08:00</updated><title type='text'>Reading a xml file-Basics</title><content type='html'>Introduction&lt;br /&gt;&lt;br /&gt;The main reason for writing this simple article is so many guys are asking doubts how to read Xml ,how to Write Xml in DotnetSpider Questions section. I Thought this article Will helpful for beginners. You can also find an article about how to write Xml document at&lt;br /&gt;http://www.dotnetspider.com/kb/SubmitSample.aspx?ArticleId=2066&lt;br /&gt;&lt;br /&gt;System.Xml namespace contains the XmlReader and XmlTextReader.&lt;br /&gt;The XmlTextReader class is derived from XmlReader class. The XmlTextReader class can be used to read the XML documents. The read function of this document reads the document until end of its nodes.&lt;br /&gt;Using the XmlTextReader class you get a forward only stream of XML data j It is then possible to handle each element as you read it without holding the entire DOM in memory.&lt;br /&gt;XmlTextReader provides direct parsing and tokenizing of XML and implements the XML 1.0 specifications&lt;br /&gt;&lt;br /&gt;This article explains how to read an Xml file.&lt;br /&gt;&lt;br /&gt;Adding NameSpace as Reference&lt;br /&gt;&lt;br /&gt;The first step in the process of reading Xml file is to add System.Xml namespace as reference to our project ,since System.Xml namespace contains the XmlReader and XmlTextReader.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;using System.Xml;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;let us assume there is an Xml file in c:\Dir\XmlExample.Xml&lt;br /&gt;&lt;br /&gt;Open an Xml Document&lt;br /&gt;&lt;br /&gt;Create an instance of an XmlTextReader object, and populate it with the XML file. Typically, the XmlTextReader class is used if you need to access the XML as raw data without the overhead of a DOM; thus, the XmlTextReader class provides a faster mechanism for reading XML.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;XmlTextReader MyReader = new XmlTextReader("c:\\dir\\XmlExample.Xml");&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;the above code opens Xml file&lt;br /&gt;&lt;br /&gt;Reading Data&lt;br /&gt;&lt;br /&gt;The Read method of the XmlTextReader class read the data. See the code&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;while (MyReader.Read())&lt;br /&gt;{&lt;br /&gt;Response.Write(MyReader.Name);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;that’s all now we are ready to read our Xml file from the above specified directory&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Read the XML File into DataSet&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can use the ReadXml method to read XML schema and data into a DataSet. XML data can be read directly from a file, a Stream object, an XmlWriter object, or a TextWriter object.&lt;br /&gt;&lt;br /&gt;The code simply looks like the following&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;string MyXmlFile =  @"c:\\Dir\\XmlExample2.xml";&lt;br /&gt;   DataSet ds =  new DataSet();&lt;br /&gt;&lt;br /&gt;   System.IO.FileStream MyReadXml   = new System.IO.FileStream(MyXmlFile,System.IO.FileMode.Open);&lt;br /&gt;            ds.ReadXml(MyReadXml);&lt;br /&gt;&lt;br /&gt;   DataGrid1.DataSource = ds;&lt;br /&gt;   DataGrid1.DataBind();&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thus we can read Xml Data into Dataset .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-2574067201532195638?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/2574067201532195638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/reading-xml-file-basics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/2574067201532195638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/2574067201532195638'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/reading-xml-file-basics.html' title='Reading a xml file-Basics'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-3821285007814263062</id><published>2010-02-26T20:50:00.000-08:00</published><updated>2010-02-26T20:56:10.658-08:00</updated><title type='text'>Paging in a DataList or Repeater control</title><content type='html'>Introduction&lt;br /&gt;DataList is a data bound list control that displays items using certain templates defined at the design time. The content of the DataList control is manipulated by using templates sections such as AlternatingItemTemplate, EditItemTemplate, FooterTemplate, HeaderTemplate, ItemTemplate, SelectedItemTemplate and SeparatorTemplate. Each of these sections has its own characteristics to be defined but at a very minimum, the ItemTemplate needs to be defined to display the items in the DataList control. Other sections can be used to provide additional look and feel to the DataList control.&lt;br /&gt;&lt;br /&gt;PagedDataSource, is a class that encapsulates the paging related properties for data-bound controls such as DataGrid, GridView, DataList, DetailsView and FormView that allow it to perform paging. And this article is going to combine both DataList control and PagedDataSource class to explain dynamic or custom paging methods for Asp.Net developers.&lt;br /&gt;&lt;br /&gt;	&lt;br /&gt;For demonstration, we are going to list out all the countries in the Country Table. We are going to create a dynamic paging control for this list and define the page size at run-time from a DropDownList control and enrich the navigation with Next and Previous buttons.&lt;br /&gt;&lt;br /&gt;Do the Basics Right&lt;br /&gt;&lt;br /&gt;Since everything comes with Ajax, create an Ajax Enabled Website, in your Visual Studio 2005. In your Default.aspx page, drag and drop a DataList control from the Toolbox, named it as dlCountry. Our country Table contains two fields such as Country_Code And Country_Name. Right click on the dlCountry datalist, choose Edit Templates &gt; Item Template. Add two Label controls into it; bind its Text property to Country_Code and Country_Name respectively.&lt;br /&gt;&lt;br /&gt;&lt;asp:DataList ID=" dlCountry" runat="server"&gt; &lt;br /&gt; &lt;ItemTemplate&gt;&lt;br /&gt;   &lt;asp:Label ID="Label1" runat="server" Text='&lt;%# Eval("Country_Code") %&gt;'&gt;&lt;/asp:Label&gt;     &lt;br /&gt;   &lt;asp:Label ID="Label2" runat="server" Text='&lt;%# Eval("Country_Name") %&gt;'&gt;&lt;/asp:Label&gt;&lt;br /&gt; &lt;/ItemTemplate&gt;&lt;br /&gt;&lt;/asp:DataList&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now switch to the Code-behind Default.aspx.cs, write a method to fetch data from the Country’s table.&lt;br /&gt;&lt;br /&gt;private void BindGrid()&lt;br /&gt;{ &lt;br /&gt;  string sql = "Select * from Country Order By Country_Name"; &lt;br /&gt;  SqlDataAdapter da = new SqlDataAdapter(sql, “Yourconnectionstring”); &lt;br /&gt;  DataTable dt = new DataTable(); &lt;br /&gt;  da.Fill(dt); &lt;br /&gt;&lt;br /&gt;  dlCountry.DataSource = dt;&lt;br /&gt;  dlCountry.DataBind();&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The above BindGrid method, fetches data from the Country table, bind it with the dlCountry datalist. So the dlCountry datalist is ready to display the records available in the Country table. Call this BindGrid method in the Page load event.&lt;br /&gt;&lt;br /&gt;	Click Here&lt;br /&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  if (!IsPostBack)&lt;br /&gt;  {&lt;br /&gt;    BindGrid();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Save everything you have done and press F5. You can see the browser opening this page and dispalys all the records in the country table. No paging available at this level.&lt;br /&gt;Let us focus On Paging&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To create dynamic paging, we are going to use PagedDataSource Class along with another DataList control. Drag and drop the second DataList control into the page, name it as dlPaging. In its ItemTemplates section, add a LinkButton name it as lnkbtnPaging. Set its CommandName property as lnkbtnPaging. Then choose End Template Editing. Drag and drop a DropdownList Control, name it as ddlPageSize, add values such as 10, 20 and 30 or something as you wish. Then add two more LinkButton controls. Name it as lnkbtnPrevious and lnkbtnNext and change its Text property as Previous and Next respectively. Place both the Previous and Next link buttons on both sides of the dlPaging datalist. Better I suggest you to put an Html Table control and place these controls in it properly so that it will look nicely aligned.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now we will work little bit on the code-behind of the Default.aspx. Declare a PagedDataSource object at page scope.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PagedDataSource pds = new PagedDataSource();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then declare a public property called CurrentPage to maintain the latest selected page index. Selected page index is stored in a ViewState variable. The default value of the ViewState is 0.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public int CurrentPage&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;  get &lt;br /&gt;  { &lt;br /&gt;    if (this.ViewState["CurrentPage"] == null) &lt;br /&gt;      return 0; &lt;br /&gt;    else &lt;br /&gt;      return Convert.ToInt16(this.ViewState["CurrentPage"].ToString()); &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; set&lt;br /&gt; { &lt;br /&gt;  this.ViewState["CurrentPage"] = value;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Next write a method ‘doPaging’ to create a list of page numbers. The total number of pages can be taken from the PagedDataSource object’s PageCount property. We create a DataTable from the information obtained from the PagedDataSource object and assign the DataTable to the dlPaging datalist.&lt;br /&gt;private void doPaging()&lt;br /&gt;{&lt;br /&gt; DataTable dt = new DataTable();&lt;br /&gt; dt.Columns.Add("PageIndex");&lt;br /&gt; dt.Columns.Add("PageText");&lt;br /&gt; for (int i = 0; i &lt; pds.PageCount; i++)&lt;br /&gt; {&lt;br /&gt;  DataRow dr = dt.NewRow(); &lt;br /&gt;  dr[0] = i; &lt;br /&gt;  dr[1] = i + 1; &lt;br /&gt;  dt.Rows.Add(dr);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; dlPaging.DataSource = dt;&lt;br /&gt; dlPaging.DataBind();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Look closely, at the doPaging method. Notice the two columns such as PageIndex and PageText. Even though it is understandable, PageIndex is the selected index value of the pages while PageText is the display value in the dlPaging Now we have to bind PageIndex and PageText into the dlPaging’s lnkbtnPaging link button. So set the CommandArgument and Text property of the lnkbtnPaging to PageIndex and PageText respectively. So the entire dlPaging datalist control’s Html source code will look like follows.&lt;br /&gt;&lt;br /&gt;&lt;asp:DataList ID=" dlPaging" runat="server" OnItemCommand="dlPaging _ItemCommand"&gt;&lt;br /&gt;&lt;ItemTemplate&gt;&lt;br /&gt;  &lt;asp:LinkButton ID="lnkbtnPaging" runat="server" CommandArgument='&lt;%# Eval("PageIndex") %&gt;' CommandName="lnkbtnPaging" Text='&lt;%# Eval("PageText") %&gt;'&gt;&lt;/asp:LinkButton&gt;&lt;br /&gt;&lt;/ItemTemplate&gt;&lt;br /&gt;&lt;/asp:DataList&gt;&lt;br /&gt;&lt;br /&gt;Modify BindGrid Method &lt;br /&gt;&lt;br /&gt;The next step is to combine both the Country listing datalist and paging number datalist controls. To start this, we are going to modify the BindGrid() method slightly.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;private void BindGrid()&lt;br /&gt;{ &lt;br /&gt;  string sql = "Select * from Country Order By Country_Name"; &lt;br /&gt;  SqlDataAdapter da = new SqlDataAdapter(sql, “Yourconnectionstring”); &lt;br /&gt;  DataTable dt = new DataTable(); &lt;br /&gt;  da.Fill(dt); &lt;br /&gt;&lt;br /&gt;  pds.DataSource = dt.DefaultView;&lt;br /&gt;  pds.AllowPaging = true;&lt;br /&gt;  pds.PageSize = Convert.ToInt16(ddlPageSize.SelectedValue);&lt;br /&gt;  pds.CurrentPageIndex = CurrentPage;&lt;br /&gt;  lnkbtnNext.Enabled = !pds.IsLastPage;&lt;br /&gt;  lnkbtnPrevious.Enabled = !pds.IsFirstPage; &lt;br /&gt;&lt;br /&gt;  dlCountry.DataSource = pds;&lt;br /&gt;  dlCountry.DataBind();&lt;br /&gt;&lt;br /&gt;  doPaging();&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the above method, as usual we fetch data from the Country table and filled it in a DataTable. Then we assign it to the DataSource of the PagedDataSource object pds. Set its AllowPaging property to true and its PageSize with the value from the ddlPageSize DropDownList control. CurrentPageIndex is assigned with our pre-defined property CurrentPage. When the page index reaches first and last page, our Previous and Next button should be disabled. So in the next two lines we check the pds whether it reaches Last or First page, accordingly we set their Enabled property. Now everything is ready to assign the pds to our Country Listing DataList. Last but not least, we are calling the doPaging method to create page numbers.&lt;br /&gt;	&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Paging Events&lt;br /&gt;&lt;br /&gt;In the ItemCommand event of the dlPaging control, write code for the paging to take place. Here we take the PageIndex value from the CommandArgument of the lnkbtnPaging and assign it to the CurrentPage property. On every event, we call the BindGrid method.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;protected void dlPaging_ItemCommand(object source, DataListCommandEventArgs e)&lt;br /&gt;{&lt;br /&gt; if (e.CommandName.Equals("lnkbtnPaging"))&lt;br /&gt; {&lt;br /&gt;   CurrentPage = Convert.ToInt16(e.CommandArgument.ToString());&lt;br /&gt;   BindGrid();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Previous And Next Button Events&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the Click events of the lnkbtnPrevious and lnkbtnNext, write a line of code that decrease and increase the value of CurrentPage property.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;protected void lnkbtnPrevious_Click(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  CurrentPage -= 1;&lt;br /&gt;  BindGrid();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void lnkbtnNext_Click(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  CurrentPage += 1;&lt;br /&gt;  BindGrid();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Change PageSize Dynamically&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To change the PageSize of the PagedDataSource dynamically, we have to call the BindGrid method again because we have already assign the value of the ddlPageSize to the PageSize property of the PagedDataSource.&lt;br /&gt;protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  CurrentPage = 0;&lt;br /&gt;  BindGrid();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;HighLight Selected Page Numbers&lt;br /&gt;&lt;br /&gt;To inform the user about the selected page, we have to highlight the Page Number in different style. This can be achived by using the following code in ItemDataBound event of the dlPaging datalist.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;protected void dlPaging_ItemDataBound(object sender, DataListItemEventArgs e)&lt;br /&gt;{&lt;br /&gt;  LinkButton lnkbtnPage = (LinkButton)e.Item.FindControl("lnkbtnPaging"); &lt;br /&gt;  if (lnkbtnPage.CommandArgument.ToString() == CurrentPage.ToString()) &lt;br /&gt;  { &lt;br /&gt;    lnkbtnPage.Enabled = false; &lt;br /&gt;    lnkbtnPage.Font.Bold = true; &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That’s it. Save everything and hit F5. You can see first DataList will display first 10 Records from the Country Table. The dlPaging control will populate the list of page numbers. Previous button will be in disabled state while Next button is active. Click on any page number, Page will navigate for the Page you choosed. Try by clicking Next and Previous buttons, then Change the ddlPageSize value.&lt;br /&gt;&lt;br /&gt;To enable Ajax to this page, add the ScriptManager and include all the control inside an UpdatePanel. Its done.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-3821285007814263062?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/3821285007814263062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/paging-in-datalist-or-repeater-control.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3821285007814263062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3821285007814263062'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/paging-in-datalist-or-repeater-control.html' title='Paging in a DataList or Repeater control'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-651909688347963482</id><published>2010-02-26T20:48:00.000-08:00</published><updated>2010-02-26T20:49:31.811-08:00</updated><title type='text'>Binding Data With ‘TreeView’ Control</title><content type='html'>Binding Data With �TreeView� Control Asp.net 2.0&lt;br /&gt;&lt;br /&gt; Over the period of few weeks I have been trying to play with asp.net 2.0 controls. As most of asp.net 2.0 beginners know there are almost no working examples and tutorials available for beta release and honestly I haven�t found people working on asp.net 2.0 so far as much as I expected.&lt;br /&gt;&lt;br /&gt;Now the real thing started when I decided to pick up some pace and started using Microsoft visual studio 2005 asp.net 2.0 instead of VS�s prior version.Among so many new tools the one which I found really fascinating in asp.net 2.0 is TreeView control, the reason is; I have been creating TreeViews on JavaScript and had really tough time integrating them with server requests/responses.&lt;br /&gt;&lt;br /&gt;Introduction of TreeView Control&lt;br /&gt;&lt;br /&gt;A tree view control displays a hierarchical list of items using lines to connect related items in a hierarchy. Each item consists of a label and an optional bitmap. Windows Explorer uses a tree view control to display directories. It displays a tree structure, or menu, that users can traverse to get to different pages in your site. A node that contains child nodes can be expanded or collapsed by clicking on it.&lt;br /&gt;&lt;br /&gt;You can use ASP.NET site Navigation features to provide a consistent way for users to navigate your site. A simple solution is to include hyperlinks that allow users to jump to other pages, presenting the hyperlinks in a list or a navigation menu. However, as your site grows, and as you move pages around in the site, it quickly becomes difficult to manage all of the links.&lt;br /&gt;&lt;br /&gt;To create a consistent, easily managed navigation solution for your site, you can use ASP.NET site navigation TreeView control.&lt;br /&gt;&lt;br /&gt;Fig: 1.0&lt;br /&gt;&lt;br /&gt;Note: you can manually populate this control by,&lt;br /&gt;1)     Clicking on TreeView control.&lt;br /&gt;2)     Right click � Edit Nodes&lt;br /&gt;3)     Under �Nodes� heading there are two buttons, to add Parent and child nodes respectively.&lt;br /&gt;&lt;br /&gt;Lets do some work now!&lt;br /&gt;&lt;br /&gt;Now that we have pretty clear understanding of TreeView control, we will quickly move on and integrate this control with our site.&lt;br /&gt;&lt;br /&gt;Step 1&lt;br /&gt;&lt;br /&gt;Create two database tables ParentTable and ChildTable, having 2 columns each.&lt;br /&gt;&lt;br /&gt;ParentTable   � [ParentName , ParentId (as PK)]&lt;br /&gt;ChildTable      � [ChildName , ParentId (as FK)]&lt;br /&gt;&lt;br /&gt;Note: you can use any database, in our example we will use Microsoft SQL server.&lt;br /&gt;&lt;br /&gt;Fig. 2.0&lt;br /&gt;&lt;br /&gt;Step 2&lt;br /&gt;&lt;br /&gt;Now that we have created our tables, open Microsoft Visual Studio 2005 and create and Asp.net 2.0 WebForm. &lt;br /&gt;&lt;br /&gt;Note: You can do this by clicking File menu and then New web site.&lt;br /&gt;While creating the new page do not uncheck Place code in separate file checkbox.&lt;br /&gt;&lt;br /&gt;Step 3&lt;br /&gt;&lt;br /&gt;Add the following LOC (Line of code) at the start of your programs along with other using keywords.&lt;br /&gt;&lt;br /&gt; using System.Data.SqlClient;&lt;br /&gt;&lt;br /&gt;Step 4&lt;br /&gt;&lt;br /&gt;Place a TreeView control on your WebForm.&lt;br /&gt;&lt;br /&gt;Note: Do not change its name, for simplicity we will use the default name TreeView1.&lt;br /&gt;&lt;br /&gt;Now double click your page, point to Page_Load event and write fill_Tree();&lt;br /&gt;&lt;br /&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        fill_Tree();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;Do not worry, we will use this function in next step.&lt;br /&gt;&lt;br /&gt;Step 5&lt;br /&gt;&lt;br /&gt;Now the real thing starts. In this step we will populate our TreeView1 control using our two tables ParentTable and ChildTable.&lt;br /&gt;&lt;br /&gt;Create a function fill_Tree()&lt;br /&gt;&lt;br /&gt;void fill_Tree()&lt;br /&gt;&lt;br /&gt;    {&lt;br /&gt;/*&lt;br /&gt;* Fill the treeview control Root Nodes From Parent Table&lt;br /&gt;* and child nodes from ChildTables&lt;br /&gt;*/ &lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Create an SQL Connection to connect to you our database&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;SqlConnection SqlCon = new SqlConnection("server=D_hameed;uid=sa;pwd=airforce;database=test");&lt;br /&gt;&lt;br /&gt;SqlCon.Open();&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Query the database&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;SqlCommand SqlCmd = new SqlCommand("Select * from ParentTable",SqlCon);&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;*Define and Populate the SQL DataReader&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;SqlDataReader Sdr = SqlCmd.ExecuteReader();&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Dispose the SQL Command to release resources&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;SqlCmd.Dispose ();&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Initialize the string ParentNode.&lt;br /&gt;* We are going to populate this string array with our            ParentTable Records&lt;br /&gt;* and then we will use this string array to populate our TreeView1 Control with parent records&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;string[,] ParentNode = new string[100, 2];&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Initialize an int variable from string array index&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;int count = 0;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Now populate the string array using our SQL Datareader Sdr.&lt;br /&gt;&lt;br /&gt;* Please Correct Code Formatting if you are pasting this code in your application.&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;while (Sdr.Read())&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;ParentNode[count, 0] = Sdr.GetValue(Sdr.GetOrdinal("ParentID")).ToString();&lt;br /&gt;ParentNode[count++, 1] = Sdr.GetValue(Sdr.GetOrdinal("ParentName")).ToString();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Close the SQL datareader to release resources&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;Sdr.Close();&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Now once the array is filled with [Parentid,ParentName]&lt;br /&gt;* start a loop to find its child module.&lt;br /&gt;* We will use the same [count] variable to loop through ChildTable&lt;br /&gt;* to find out the number of child associated with ParentTable.&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;for (int loop = 0; loop &lt; count; loop++)&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* First create a TreeView1 node with ParentName and than&lt;br /&gt;* add ChildName to that node&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;            TreeNode root = new TreeNode();&lt;br /&gt;            root.Text = ParentNode[loop, 1];&lt;br /&gt;            root.Target = "_blank";&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Give the url of your page&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;      root.NavigateUrl = "mypage.aspx";&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Now that we have [ParentId] in our array we can find out child modules&lt;br /&gt;&lt;br /&gt;* Please Correct Code Formatting if you are pasting this code in your application.&lt;br /&gt;&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;SqlCommand Module_SqlCmd = new SqlCommand("Select * from ChildTable where ParentId =" + ParentNode[loop, 0], SqlCon);&lt;br /&gt;&lt;br /&gt;SqlDataReader Module_Sdr = Module_SqlCmd.ExecuteReader();&lt;br /&gt;&lt;br /&gt;            while (Module_Sdr.Read())&lt;br /&gt;            {&lt;br /&gt;&lt;br /&gt;// Add children module to the root node&lt;br /&gt;&lt;br /&gt;                TreeNode child = new TreeNode();&lt;br /&gt;&lt;br /&gt;                child.Text = Module_Sdr.GetValue(Module_Sdr.GetOrdinal("ChildName")).ToString();&lt;br /&gt;&lt;br /&gt;                child.Target = "_blank";&lt;br /&gt;&lt;br /&gt;                child.NavigateUrl = "your_page_Url.aspx";&lt;br /&gt;&lt;br /&gt;                root.ChildNodes.Add(child);&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;             Module_Sdr.Close();&lt;br /&gt;&lt;br /&gt; // Add root node to TreeView&lt;br /&gt;           TreeView1.Nodes.Add(root);&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* By Default, when you populate TreeView Control programmatically, it expends all nodes.&lt;br /&gt;*/&lt;br /&gt;            TreeView1.CollapseAll();&lt;br /&gt;   SqlCon.Close();&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt; Lets see how it looks like!&lt;br /&gt;&lt;br /&gt; Fig. 3.0&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-651909688347963482?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/651909688347963482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/binding-data-with-treeview-control.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/651909688347963482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/651909688347963482'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/binding-data-with-treeview-control.html' title='Binding Data With ‘TreeView’ Control'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-2598992112167126108</id><published>2010-02-10T20:00:00.000-08:00</published><updated>2010-02-10T20:01:20.459-08:00</updated><title type='text'>displaying xml with xslt</title><content type='html'>Displaying XML with XSLT&lt;br /&gt;&lt;br /&gt;XSLT is the recommended style sheet language of XML.&lt;br /&gt;&lt;br /&gt;XSLT (eXtensible Stylesheet Language Transformations) is far more sophisticated than CSS.&lt;br /&gt;&lt;br /&gt;XSLT can be used to transform XML into HTML, before it is displayed by a browser:&lt;br /&gt;&lt;br /&gt;Display XML with XSLT&lt;br /&gt;&lt;br /&gt;If you want to learn more about XSLT, find our XSLT tutorial on our homepage.&lt;br /&gt;Transforming XML with XSLT on the Server&lt;br /&gt;&lt;br /&gt;In the example above, the XSLT transformation is done by the browser, when the browser reads the XML file.&lt;br /&gt;&lt;br /&gt;Different browsers may produce different result when transforming XML with XSLT. To reduce this problem the XSLT transformation can be done on the server.&lt;br /&gt;&lt;br /&gt;View the result.&lt;br /&gt;&lt;br /&gt;Note that the result of the output is exactly the same, either the transformation is done by the web server or by the web browser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-2598992112167126108?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/2598992112167126108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/displaying-xml-with-xslt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/2598992112167126108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/2598992112167126108'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/displaying-xml-with-xslt.html' title='displaying xml with xslt'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-1531453331309753968</id><published>2010-02-10T19:57:00.000-08:00</published><updated>2010-02-10T20:00:32.802-08:00</updated><title type='text'>xml tree example</title><content type='html'>XML Tree&lt;br /&gt;« Previous 	Next Chapter »&lt;br /&gt;&lt;br /&gt;XML documents form a tree structure that starts at "the root" and branches to "the leaves".&lt;br /&gt;An Example XML Document&lt;br /&gt;&lt;br /&gt;XML documents use a self-describing and simple syntax:&lt;br /&gt;&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;&lt;br /&gt;&lt;note&gt;&lt;br /&gt;  &lt;to&gt;Tove&lt;/to&gt;&lt;br /&gt;  &lt;from&gt;Jani&lt;/from&gt;&lt;br /&gt;  &lt;heading&gt;Reminder&lt;/heading&gt;&lt;br /&gt;  &lt;body&gt;Don't forget me this weekend!&lt;/body&gt;&lt;br /&gt;&lt;/note&gt;&lt;br /&gt;&lt;br /&gt;The first line is the XML declaration. It defines the XML version (1.0) and the encoding used (ISO-8859-1 = Latin-1/West European character set).&lt;br /&gt;&lt;br /&gt;The next line describes the root element of the document (like saying: "this document is a note"):&lt;br /&gt;&lt;note&gt;&lt;br /&gt;&lt;br /&gt;The next 4 lines describe 4 child elements of the root (to, from, heading, and body):&lt;br /&gt;&lt;to&gt;Tove&lt;/to&gt;&lt;br /&gt;&lt;from&gt;Jani&lt;/from&gt;&lt;br /&gt;&lt;heading&gt;Reminder&lt;/heading&gt;&lt;br /&gt;&lt;body&gt;Don't forget me this weekend!&lt;/body&gt;&lt;br /&gt;&lt;br /&gt;And finally the last line defines the end of the root element:&lt;br /&gt;&lt;/note&gt;&lt;br /&gt;&lt;br /&gt;You can assume, from this example, that the XML document contains a note to Tove from Jani.&lt;br /&gt;&lt;br /&gt;Don't you agree that XML is pretty self-descriptive?&lt;br /&gt;XML Documents Form a Tree Structure&lt;br /&gt;&lt;br /&gt;XML documents must contain a root element. This element is "the parent" of all other elements.&lt;br /&gt;&lt;br /&gt;The elements in an XML document form a document tree. The tree starts at the root and branches to the lowest level of the tree.&lt;br /&gt;&lt;br /&gt;All elements can have sub elements (child elements):&lt;br /&gt;&lt;root&gt;&lt;br /&gt;  &lt;child&gt;&lt;br /&gt;    &lt;subchild&gt;.....&lt;/subchild&gt;&lt;br /&gt;  &lt;/child&gt;&lt;br /&gt;&lt;/root&gt;&lt;br /&gt;&lt;br /&gt;The terms parent, child, and sibling are used to describe the relationships between elements. Parent elements have children. Children on the same level are called siblings (brothers or sisters).&lt;br /&gt;&lt;br /&gt;All elements can have text content and attributes (just like in HTML).&lt;br /&gt;Example:&lt;br /&gt;DOM node tree&lt;br /&gt;&lt;br /&gt;The image above represents one book in the XML below:&lt;br /&gt;&lt;bookstore&gt;&lt;br /&gt;  &lt;book category="COOKING"&gt;&lt;br /&gt;    &lt;title lang="en"&gt;Everyday Italian&lt;/title&gt;&lt;br /&gt;    &lt;author&gt;Giada De Laurentiis&lt;/author&gt;&lt;br /&gt;    &lt;year&gt;2005&lt;/year&gt;&lt;br /&gt;    &lt;price&gt;30.00&lt;/price&gt;&lt;br /&gt;  &lt;/book&gt;&lt;br /&gt;  &lt;book category="CHILDREN"&gt;&lt;br /&gt;    &lt;title lang="en"&gt;Harry Potter&lt;/title&gt;&lt;br /&gt;    &lt;author&gt;J K. Rowling&lt;/author&gt;&lt;br /&gt;    &lt;year&gt;2005&lt;/year&gt;&lt;br /&gt;    &lt;price&gt;29.99&lt;/price&gt;&lt;br /&gt;  &lt;/book&gt;&lt;br /&gt;  &lt;book category="WEB"&gt;&lt;br /&gt;    &lt;title lang="en"&gt;Learning XML&lt;/title&gt;&lt;br /&gt;    &lt;author&gt;Erik T. Ray&lt;/author&gt;&lt;br /&gt;    &lt;year&gt;2003&lt;/year&gt;&lt;br /&gt;    &lt;price&gt;39.95&lt;/price&gt;&lt;br /&gt;  &lt;/book&gt;&lt;br /&gt;&lt;/bookstore&gt;&lt;br /&gt;&lt;br /&gt;The root element in the example is &lt;bookstore&gt;. All &lt;book&gt; elements in the document are contained within &lt;bookstore&gt;.&lt;br /&gt;&lt;br /&gt;The &lt;book&gt; element has 4 children: &lt;title&gt;,&lt; author&gt;, &lt;year&gt;, &lt;price&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-1531453331309753968?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/1531453331309753968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/xml-tree-example.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1531453331309753968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1531453331309753968'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/xml-tree-example.html' title='xml tree example'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-3606349332059425106</id><published>2010-02-10T19:53:00.000-08:00</published><updated>2010-02-10T19:57:01.008-08:00</updated><title type='text'>Javascript Regular Expression object</title><content type='html'>RegExp, is short for regular expression.&lt;br /&gt;Complete RegExp Object Reference&lt;br /&gt;&lt;br /&gt;For a complete reference of all the properties and methods that can be used with the RegExp object, go to our complete RegExp object reference.&lt;br /&gt;&lt;br /&gt;The reference contains a brief description and examples of use for each property and method!&lt;br /&gt;What is RegExp?&lt;br /&gt;&lt;br /&gt;A regular expression is an object that describes a pattern of characters.&lt;br /&gt;&lt;br /&gt;When you search in a text, you can use a pattern to describe what you are searching for.&lt;br /&gt;&lt;br /&gt;A simple pattern can be one single character.&lt;br /&gt;&lt;br /&gt;A more complicated pattern can consist of more characters, and can be used for parsing, format checking, substitution and more.&lt;br /&gt;&lt;br /&gt;Regular expressions are used to perform powerful pattern-matching and "search-and-replace" functions on text.&lt;br /&gt;Syntax&lt;br /&gt;var txt=new RegExp(pattern,modifiers);&lt;br /&gt;&lt;br /&gt;or more simply:&lt;br /&gt;&lt;br /&gt;var txt=/pattern/modifiers;&lt;br /&gt;&lt;br /&gt;    * pattern specifies the pattern of an expression&lt;br /&gt;    * modifiers specify if a search should be global, case-sensitive, etc.&lt;br /&gt;&lt;br /&gt;RegExp Modifiers&lt;br /&gt;&lt;br /&gt;Modifiers are used to perform case-insensitive and global searches.&lt;br /&gt;&lt;br /&gt;The i modifier is used to perform case-insensitive matching.&lt;br /&gt;&lt;br /&gt;The g modifier is used to perform a global match (find all matches rather than stopping after the first match).&lt;br /&gt;Example 1&lt;br /&gt;&lt;br /&gt;Do a case-insensitive search for "w3schools" in a string:&lt;br /&gt;var str="Visit W3Schools";&lt;br /&gt;var patt1=/w3schools/i;&lt;br /&gt;&lt;br /&gt;The marked text below shows where the expression gets a match:&lt;br /&gt;Visit W3Schools&lt;br /&gt;&lt;br /&gt;Try it yourself »&lt;br /&gt;&lt;br /&gt;Example 2&lt;br /&gt;&lt;br /&gt;Do a global search for "is":&lt;br /&gt;var str="Is this all there is?";&lt;br /&gt;var patt1=/is/g;&lt;br /&gt;&lt;br /&gt;The marked text below shows where the expression gets a match:&lt;br /&gt;Is this all there is?&lt;br /&gt;&lt;br /&gt;Try it yourself »&lt;br /&gt;&lt;br /&gt;Example 3&lt;br /&gt;&lt;br /&gt;Do a global, case-insensitive search for "is":&lt;br /&gt;var str="Is this all there is?";&lt;br /&gt;var patt1=/is/gi;&lt;br /&gt;&lt;br /&gt;The marked text below shows where the expression gets a match:&lt;br /&gt;Is this all there is?&lt;br /&gt;&lt;br /&gt;Try it yourself »&lt;br /&gt;&lt;br /&gt;test()&lt;br /&gt;&lt;br /&gt;The test() method searches a string for a specified value, and returns true or false, depending on the result.&lt;br /&gt;&lt;br /&gt;The following example searches a string for the character "e":&lt;br /&gt;Example&lt;br /&gt;var patt1=new RegExp("e");&lt;br /&gt;document.write(patt1.test("The best things in life are free"));&lt;br /&gt;&lt;br /&gt;Since there is an "e" in the string, the output of the code above will be:&lt;br /&gt;true&lt;br /&gt;&lt;br /&gt;Try it yourself »&lt;br /&gt;&lt;br /&gt;exec()&lt;br /&gt;&lt;br /&gt;The exec() method searches a string for a specified value, and returns the text of the found value. If no match is found, it returns null.&lt;br /&gt;&lt;br /&gt;The following example searches a string for the character "e":&lt;br /&gt;Example 1&lt;br /&gt;var patt1=new RegExp("e");&lt;br /&gt;document.write(patt1.exec("The best things in life are free"));&lt;br /&gt;&lt;br /&gt;Since there is an "e" in the string, the output of the code above will be:&lt;br /&gt;e&lt;br /&gt;&lt;br /&gt;Try it yourself »&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-3606349332059425106?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/3606349332059425106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/javascript-regular-expression-object.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3606349332059425106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3606349332059425106'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/javascript-regular-expression-object.html' title='Javascript Regular Expression object'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-4574219839971931647</id><published>2010-02-10T19:50:00.000-08:00</published><updated>2010-02-10T19:53:32.623-08:00</updated><title type='text'>javascript to create clock.</title><content type='html'>function startTime()&lt;br /&gt;{&lt;br /&gt;var today=new Date();&lt;br /&gt;var h=today.getHours();&lt;br /&gt;var m=today.getMinutes();&lt;br /&gt;var s=today.getSeconds();&lt;br /&gt;// add a zero in front of numbers&lt;10&lt;br /&gt;m=checkTime(m);&lt;br /&gt;s=checkTime(s);&lt;br /&gt;document.getElementById('txt').innerHTML=h+":"+m+":"+s;&lt;br /&gt;t=setTimeout('startTime()',500);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function checkTime(i)&lt;br /&gt;{&lt;br /&gt;if (i&lt;10)&lt;br /&gt;  {&lt;br /&gt;  i="0" + i;&lt;br /&gt;  }&lt;br /&gt;return i;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-4574219839971931647?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/4574219839971931647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/javascript-to-create-clock.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/4574219839971931647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/4574219839971931647'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/javascript-to-create-clock.html' title='javascript to create clock.'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-5345048256291738178</id><published>2010-02-10T19:45:00.000-08:00</published><updated>2010-02-10T19:50:07.045-08:00</updated><title type='text'>SQL Table Relations, Primary and Foreign Keys, and Normalization</title><content type='html'>So far in all SQL examples we had we were dealing with a single table. The truth is that in real life when dealing with databases you’ll have to work with many tables, which are interrelated. The true power of the Relational Database Management Systems is the fact that they are Relational.&lt;br /&gt;&lt;br /&gt;The relationships in a RDBMS ensure that there is no redundant data. What is redundant data, you might ask? I’ll answer you with example. An online store, offers computers for sale and the easiest way to track the sales will be to keep them in a database. You can have a table called Product, which will hold information about each computer - model name, price and the manufacturer. You also need to keep some details about the manufacturer like their website and their support email. If you store the manufacturer details in the Product table, you will have the manufacturer contact info repeated for each computer model the manufacturer produces:&lt;br /&gt;&lt;br /&gt;model Price Manufacturer ManufacturerWebsite ManufacturerEmail&lt;br /&gt;Inspiron B120 $499 Dell http://www.dell.com support@dell.com&lt;br /&gt;Inspiron B130 $599 Dell http://www.dell.com support@dell.com&lt;br /&gt;Inspiron E1705 $949 Dell http://www.dell.com support@dell.com&lt;br /&gt;Satellite A100 $549 Toshiba http://www.toshiba.com support@toshiba.com&lt;br /&gt;Satellite P100 $934 Toshiba http://www.toshiba.com support@toshiba.com&lt;br /&gt;&lt;br /&gt;To get rid of the redundant manufacturer data in the Product table, we can create a new table called Manufacturer, which will have only one entry (row) for each manufacturer and we can link (relate) this table to the Product table. To create this relation we need to add additional column in the Product table that references the entries in the Manufacturer table.&lt;br /&gt;&lt;br /&gt;A relationship between 2 tables is established when the data in one of the columns in the first table matches the data in a column in the second table. To explain this further we have to understand SQL relational concepts – Primary Key and Foreign Key. Primary Key is a column or a combination of columns that uniquely identifies each row in a table.&lt;br /&gt;Foreign Key is a column or a combination of columns whose values match a Primary Key in a different table. In the most common scenario the relationship between 2 tables matches the Primary Key in one of the tables with a Foreign Key in the second table. Consider the new Product and Manufacturer tables below:&lt;br /&gt;&lt;br /&gt;Manufacturer&lt;br /&gt;ManufacturerID Manufacturer ManufacturerWebsite ManufacturerEmail&lt;br /&gt;1 Dell http://www.dell.com support@dell.com&lt;br /&gt;2 Toshiba http://www.toshiba.com support@toshiba.com&lt;br /&gt;&lt;br /&gt;Product&lt;br /&gt;model Price ManufacturerID&lt;br /&gt;Inspiron B120 $499 1&lt;br /&gt;Inspiron B130 $599 1&lt;br /&gt;Inspiron E1705 $949 1&lt;br /&gt;Satellite A100 $549 2&lt;br /&gt;Satellite P100 $934 2&lt;br /&gt;&lt;br /&gt;The first table is Manufacturer which has 2 entries for Dell and Toshiba respectively. Each of these entries has a ManufacturerID value, which is unique integer number. Because the ManufacturerID column is unique for the Manufacturer table we can use it as a Primary Key in this table. The Product table retains the Model and the Price columns, but has a new column called ManufacturerID, which matches the values of the ManufacturerID column in the Manufacturer table. All values in the ManufacturerID column in the Product table have to match one of the values in the Manufacturer table Primary Key (for example you can’t have ManufacturerID with value of 3 in the Product table, simply because there is no manufacturer with this ManufacturerID defined in the Manufacturer table).&lt;br /&gt;&lt;br /&gt;I’m sure you’ve noticed that we used the same name for the Primary Key in the first table as for the Foreign Key in the second. This was done on purpose to show the relationship between the 2 tables based on these columns. Of course you can call the 2 columns with different names, but if somebody sees your database for a first time it won’t be immediately clear that these 2 tables are related.&lt;br /&gt;&lt;br /&gt;But how do we ensure that the Product table doesn’t have invalid entries like the last entry below:&lt;br /&gt;&lt;br /&gt;model Price ManufacturerID&lt;br /&gt;Inspiron B120 $499 1&lt;br /&gt;Inspiron B130 $599 1&lt;br /&gt;Inspiron E1705 $949 1&lt;br /&gt;Satellite A100 $549 2&lt;br /&gt;Satellite P100 $934 2&lt;br /&gt;ThinkPad Z60t $849 3&lt;br /&gt;&lt;br /&gt;We do not have a manufacturer with ManufacturerID of 3 in our Manufacturer table, hence this entry in the Product table is invalid. The answer is that you have to enforce referential integrity between the 2 tables. Different RDBMS have different ways to enforce referential integrity, and I will not go into more details as this is not important to understand the concept of relationship between tables.&lt;br /&gt;&lt;br /&gt;There are 3 types of relations between tables – One-To-Many, Many-To-Many and One-To-One. The relation we created above is One-To-Many and is the most common of the 3 types. In One-To-Many relation a row in one of the tables can have many matching rows in the second table, but a row the second table can match only one row in the first table.&lt;br /&gt;&lt;br /&gt;In our example, each manufacturer (a row in the Manufacturer table) produces several different computer models (several rows in the Product table), but each particular product (a row in the Product table) has only one manufacturer (a row in the Manufacturer table).&lt;br /&gt;&lt;br /&gt;The second type is the Many-To-Many relation. In this relation many rows from the first table can match many rows in the second and the other way around. To define this type of relation you need a third table whose primary key is composed of the 2 foreign keys from the other 2 table. To clarify this relation lets review the following example. We have a Article table (ArticleID is primary key) and Category (CategoryID is primary key) table.&lt;br /&gt;Every article published in the Article table can belong to multiple categories. To accommodate that, we create a new table called ArticleCategory, which has only 2 columns – ArticleID and CategoryID (these 2 columns form the primary key for this table). This new table called sometimes junction table defines the Many-To-Many relationship between the 2 main tables. One article can belong to multiple categories, and every category may contain more than one article.&lt;br /&gt;&lt;br /&gt;In the One-To-One relation each row in the first table may match only one row in the second and the other way around. This relationship is very uncommon simply because if you have this type of relation you may as well keep all the info in one single table.&lt;br /&gt;&lt;br /&gt;By dividing the data into 2 tables we successfully removed the redundant manufacturer details from the initial Product table adding an integer column referencing the new Manufacturer table instead.&lt;br /&gt;&lt;br /&gt;The process of removing redundant data by creating relations between tables is known as Normalization. Normalization process uses formal methods to design the database in interrelated tables.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-5345048256291738178?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/5345048256291738178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/sql-table-relations-primary-and-foreign.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5345048256291738178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5345048256291738178'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/sql-table-relations-primary-and-foreign.html' title='SQL Table Relations, Primary and Foreign Keys, and Normalization'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-1900544406093608094</id><published>2010-02-10T19:43:00.000-08:00</published><updated>2010-02-10T19:45:44.270-08:00</updated><title type='text'>Using StringBuilder in .NET</title><content type='html'>StringBuilder has an Append method that returns a reference to itself. This is useful for when you want to append several items in one go. The following code is an example. Obviously, you'll get more benefit the more items you add:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      StringBuilder sb = new StringBuilder( ) ;&lt;br /&gt;      string s = sb.Append( @"Hello " )&lt;br /&gt;        .Append( @"World" )&lt;br /&gt;        .ToString( ) ;&lt;br /&gt;&lt;br /&gt;Editors Note: Here's the equivalent in VB.NET, which isn't quite as useful because you have to append the line breaks and, interestingly, the "dot" (.) has to go at the ends of the lines or you have to put the .Append at the end of the lines as shown. In other words, this works:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      Dim sb As StringBuilder = New StringBuilder&lt;br /&gt;      Dim s As String = sb.Append("Hello "). _&lt;br /&gt;      Append("World"). _&lt;br /&gt;      Append("Junk"). _&lt;br /&gt;      ToString()&lt;br /&gt;&lt;br /&gt;...and this works too:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      Dim sb As StringBuilder = New StringBuilder&lt;br /&gt;      Dim s As String = sb.Append("Hello ").Append _&lt;br /&gt;      ("World").Append _&lt;br /&gt;      ("Junk").ToString&lt;br /&gt;&lt;br /&gt;...but this doesn't:&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;      Dim sb As StringBuilder = New StringBuilder&lt;br /&gt;      Dim s As String = sb.Append("Hello ") _&lt;br /&gt;      .Append("World") _&lt;br /&gt;      .Append("Junk") _&lt;br /&gt;      .ToString()&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-1900544406093608094?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/1900544406093608094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/using-stringbuilder-in-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1900544406093608094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1900544406093608094'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/using-stringbuilder-in-net.html' title='Using StringBuilder in .NET'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-4929904597573511587</id><published>2010-02-10T19:41:00.000-08:00</published><updated>2010-02-10T19:43:44.144-08:00</updated><title type='text'>Introducing LINQ: Language‐Integrated Query</title><content type='html'>Problem: Data != Objects&lt;br /&gt;Developers live in two worlds: The world of objects and the world of data. One of the things that makes&lt;br /&gt;developers’ lives more difficult is the impedance mismatch between these two worlds and the&lt;br /&gt;inordinate amount of plumbing code required to bridge the gap between them. For example, we might&lt;br /&gt;want to retrieve customer data from a relational database, display it to the user for updating, then save&lt;br /&gt;those changes back to the database. The traditional approach is to rely on an API like ADO.NET for the&lt;br /&gt;data‐centric operations, potentially sacrificing on type‐safety and compiler syntax checking, and utilize&lt;br /&gt;object‐oriented programming techniques for other parts of our application. Where these two worlds&lt;br /&gt;intersect in our application, we are forced to deal with differences between the SQL and CLR type&lt;br /&gt;systems, how entity relations work, as well as other incompatibilities. Conversely, we may wish to deal&lt;br /&gt;with objects in a data‐centric fashion, filtering, sorting and grouping collections of objects, but this&lt;br /&gt;means we may end up with code that is difficult to maintain because it obscures what we want to do at&lt;br /&gt;a higher level.&lt;br /&gt;The Missing LINQ&lt;br /&gt;Not wanting us to languish in this no man’s land, the good folks at Microsoft, led by Anders Hejlsberg&lt;br /&gt;(chief architect of the C# programming language), have created the LINQ Project. LINQ stands for&lt;br /&gt;Language‐Integrated Query and seeks to make query a first‐class citizen of the programming language.&lt;br /&gt;Microsoft plans to incorporate LINQ into C# 3.0 and Visual Basic 9.0, both of which will be released with&lt;br /&gt;Visual Studio 2008 (code‐named Orcas). By introducing a SQL‐like syntax, LINQ allows you to interrogate&lt;br /&gt;an in‐memory collection (anything implementing IEnumerable&lt;T&gt;), filter the results, group, sort,&lt;br /&gt;transform and perform a number of other data‐centric operations. Take, for example, the following&lt;br /&gt;array of strings:&lt;br /&gt;string[] stooges = { "Moe", "Larry", "Curly", "Shemp" };&lt;br /&gt;With C# 3.0’s new query syntax, you can extract only strings with a length of 5, sort them alphabetically,&lt;br /&gt;and change the results to upper case:&lt;br /&gt;IEnumerable&lt;string&gt; query =&lt;br /&gt;from s in stooges&lt;br /&gt;where s.Length == 5&lt;br /&gt;orderby s&lt;br /&gt;Page 2 of 6&lt;br /&gt;select s.ToUpper();&lt;br /&gt;In this snippet, from s in stooges indicates that you want to query the stooges collection and&lt;br /&gt;use s to represent each item in the sequence. The select clause determines the data you want&lt;br /&gt;returned and what shape it should take. Here we want to return each element converted to upper case.&lt;br /&gt;The where and orderby clauses, as you might guess, restrict the results to those with 5 characters&lt;br /&gt;and specify an ascending sort. Execution of the query is actually deferred until you iterate the query&lt;br /&gt;results, typically with a foreach statement, or by calling extension methods, such as ToArray or ToList,&lt;br /&gt;that perform the iteration internally (we’ll talk about extension methods in just a bit). The following&lt;br /&gt;statement triggers the query execution:&lt;br /&gt;foreach (string s in query) Console.WriteLine(s);&lt;br /&gt;This produces the following output:&lt;br /&gt;CURLY&lt;br /&gt;LARRY&lt;br /&gt;SHEMP&lt;br /&gt;Behind the Magic: C# Language Enhancements&lt;br /&gt;Supporting language‐integrated query is a set of powerful enhancements to the C# programming&lt;br /&gt;language, each of which is useful in its own right, but when taken together provide the basis for LINQ.&lt;br /&gt;The most significant of these is extension methods, which allow third parties to in essence add methods&lt;br /&gt;to a type, thereby augmenting the type’s contract, while still allowing the type’s author to provide his or&lt;br /&gt;her own implementations of these methods. Extension methods are nothing more than static methods&lt;br /&gt;defined in static classes, and (in C#) have the operator in front of the first method parameter. The&lt;br /&gt;System.Linq namespace contains what are called the standard query operators, which are extension&lt;br /&gt;methods that provide the basic functionality of LINQ. The C# compiler, in fact, converts query syntax&lt;br /&gt;(things like from, in, where, select) to extension method calls. One of these is the simplest query&lt;br /&gt;operator, Where:&lt;br /&gt;namespace System.Linq&lt;br /&gt;{&lt;br /&gt;public static class Enumerable&lt;br /&gt;{&lt;br /&gt;public static IEnumerable&lt;T&gt; Where&lt;T&gt;&lt;br /&gt;Page 3 of 6&lt;br /&gt;(this IEnumerable&lt;T&gt; source, Func&lt;T, bool&gt; predicate)&lt;br /&gt;{&lt;br /&gt;foreach (T item in source)&lt;br /&gt;{&lt;br /&gt;if (predicate(item)) yield return item;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;As you can see, the method accepts a source of type IEnumerable&lt;T&gt; and a predicate of the Func&lt;br /&gt;generic delegate type. We can create an instance of the delegate as an anonymous method:&lt;br /&gt;Func&lt;string, bool&gt; predicate = delegate(string s)&lt;br /&gt;{ return s.Length == 5; };&lt;br /&gt;The Where method simply iterates over the source, returning only items that pass the predicate test.&lt;br /&gt;Because it’s defined as a static method, there’s nothing to prevent you from calling it directly, like so:&lt;br /&gt;IEnumerable&lt;string&gt; query = Enumerable.Where(stooges, predicate);&lt;br /&gt;However, because Where is defined as an extension method, we can invoke it using instance syntax&lt;br /&gt;(note, however, that it’s not really an instance method!):&lt;br /&gt;IEnumerable&lt;string&gt; query = stooges.Where(predicate);&lt;br /&gt;Extension methods are brought into scope when the namespace in which they are contained is imported&lt;br /&gt;with a using directive. However, they are only used if no matching methods with the same name and&lt;br /&gt;signature exist on the target type or its base classes. This lets you plug in your own query operators&lt;br /&gt;which take precedence over those in the System.Linq namespace.&lt;br /&gt;Although you can define the predicate as an anonymous method (or a standalone method for that&lt;br /&gt;matter), C# provides a much more compact syntax, called a lambda expression. If we were to re‐write&lt;br /&gt;our anonymous method as a lambda expression and pass it as an argument, our call to Where would&lt;br /&gt;look like this (notice how the type of “s” is inferred and “return” is left out):&lt;br /&gt;Page 4 of 6&lt;br /&gt;IEnumerable&lt;string&gt; query = stooges.Where(s =&gt; s.Length == 5);&lt;br /&gt;The power of lambda expressions, however, is not just that they are compact (and hence more readable&lt;br /&gt;when passed as method parameters), but they can be compiled as either code or data. When assigned&lt;br /&gt;to the generic type Expression&lt;T&gt;, the compiler emits an expression tree representing the code rather&lt;br /&gt;than IL that would execute the code. Frameworks like LINQ to SQL can then analyze the expression tree&lt;br /&gt;to formulate SQL statements targeting a relational database.&lt;br /&gt;Bridging the Gap: LINQ to SQL, Linq to XML&lt;br /&gt;Besides enabling you to query in‐memory collections, LINQ is based on an extensible architecture that&lt;br /&gt;allows you to plug in a query processing engine to fetch data from any external source. In fact, the first&lt;br /&gt;version of LINQ comes with both these capabilities, called LINQ to SQL and LINQ to XML, respectively.&lt;br /&gt;Combining these LINQ extensions, you could retrieve a list of products from the Northwind database,&lt;br /&gt;place the result in an in‐memory collection, massage the data, then persist the output to an XML file, all&lt;br /&gt;without having to translate “foreign” data constructs into CLR objects, while at the same time benefiting&lt;br /&gt;from Intellisense and compile‐time syntax checking. Let’s start by querying relational data using LINQ to&lt;br /&gt;SQL:&lt;br /&gt;NorthwindDataContext db = new NorthwindDataContext();&lt;br /&gt;IEnumerable&lt;Product&gt; prodQuery =&lt;br /&gt;from p in db.Products&lt;br /&gt;where p.Category.CategoryName == "Beverages"&lt;br /&gt;select p;&lt;br /&gt;The NorthwindDataContext class derives from DataContext, which does the heavy lifting to&lt;br /&gt;convert the query expression into SQL, execute it against the database, and return the results as a&lt;br /&gt;sequence of Product objects. Where, might you ask, are these classes defined? It just so happens&lt;br /&gt;that Visual Studio 2008 comes with special tool support for LINQ to SQL, including a class designer&lt;br /&gt;(which you get when adding a “LINQ to SQL Classes” item to a project). The designer generates the&lt;br /&gt;NorthwindDataContext and Product classes when you drag the Products table from a data&lt;br /&gt;connection in the Server Explorer onto the class designer. If you bring over multiple tables, relations&lt;br /&gt;between the tables are reflected in the class diagram and become object properties in the designergenerated&lt;br /&gt;code.&lt;br /&gt;Page 5 of 6&lt;br /&gt;Notice how the where clause in our query references the CategoryName property of the Category class,&lt;br /&gt;which is shown to be a property of the Product class. When you execute this query, LINQ to SQL&lt;br /&gt;generates a SQL statement that includes a JOIN on the Products and Categories tables. The join is&lt;br /&gt;performed by SQL Server, which makes for efficient query execution. You can see this take place by&lt;br /&gt;setting the Log property of the data context to dump output to the console window or a text file.&lt;br /&gt;SELECT * FROM [dbo].[Products] AS [t0]&lt;br /&gt;LEFT OUTER JOIN [dbo].[Categories] AS [t1]&lt;br /&gt;ON [t1].[CategoryID] = [t0].[CategoryID]&lt;br /&gt;WHERE [t1].[CategoryName] = @p0&lt;br /&gt;-- @p0: Input String (Size = 9; Prec = 0; Scale = 0) [Beverages]&lt;br /&gt;LINQ to SQL also includes support for tracking changes to in‐memory objects, then posting those&lt;br /&gt;changes back to the database, while at the same time maintaining concurrency control. (If you like, you&lt;br /&gt;can also specify stored procedures for the updates.) For example, we can store our product list in a local&lt;br /&gt;collection, change the unit price of an item, then call SubmitChanges to persist the new data back to&lt;br /&gt;SQL Server.&lt;br /&gt;List&lt;Product&gt; products = prodQuery.ToList();&lt;br /&gt;Product chai = (from p in products&lt;br /&gt;where p.ProductName == "Chai"&lt;br /&gt;select p).Single();&lt;br /&gt;chai.UnitPrice = 20;&lt;br /&gt;db.SubmitChanges();&lt;br /&gt;Page 6 of 6&lt;br /&gt;The ORM functionality of LINQ to SQL is somewhat limited (for example, many‐to‐many relationships&lt;br /&gt;aren’t fully supported and it only works with SQL Server). But the power of LINQ really shines when&lt;br /&gt;combining LINQ to Objects, LINQ to SQL and LINQ to XML. We can, for instance, take our list of&lt;br /&gt;beverages, sort them, and save them as an XML file.&lt;br /&gt;IEnumerable&lt;XElement&gt; xmlQuery =&lt;br /&gt;from p in products&lt;br /&gt;orderby p.ProductName&lt;br /&gt;select new XElement("Product",&lt;br /&gt;new XAttribute("ProductName", p.ProductName),&lt;br /&gt;new XAttribute("UnitPrice", p.UnitPrice));&lt;br /&gt;XElement bevXml = new XElement("Beverages", xmlQuery);&lt;br /&gt;bevXml.Save("beverages.xml");&lt;br /&gt;Notice how this code, unlike the DOM API, is element‐centric, as opposed to document‐centric, and that&lt;br /&gt;there’s no need for XPath query strings. Nice. The beverages.xml file looks like this:&lt;br /&gt;&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;br /&gt;&lt;Beverages&gt;&lt;br /&gt;&lt;Product ProductName="Chai" UnitPrice="20.0000" /&gt;&lt;br /&gt;&lt;Product ProductName="Chang" UnitPrice="19.0000" /&gt;&lt;br /&gt;&lt;Product ProductName="Chartreuse verte" UnitPrice="18.0000" /&gt;&lt;br /&gt;&lt;Product ProductName="Côte de Blaye" UnitPrice="263.5000" /&gt;&lt;br /&gt;[Remaining items elided for clarity ...]&lt;br /&gt;&lt;/Beverages&gt;&lt;br /&gt;Time to LINQ Up!&lt;br /&gt;There is much more to LINQ than what I have room to cover here. Other C# features driving LINQ are&lt;br /&gt;things like object initializers, anonymous types and implicitly typed local variables. There are standard&lt;br /&gt;query operators that perform grouping, joins, partitioning, union, intersection, aggregation and&lt;br /&gt;conversion, and other functions as well. And while LINQ does not completely resolve impedance&lt;br /&gt;mismatch between objects and data, it is a step in the right direction, resulting in cleaner code that&lt;br /&gt;more clearly reflects the developer’s intention. It also makes you more productive by eliminating much&lt;br /&gt;of the plumbing code you would otherwise have to write, which, after all, is what frameworks are all&lt;br /&gt;about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-4929904597573511587?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/4929904597573511587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/introducing-linq-languageintegrated.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/4929904597573511587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/4929904597573511587'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/introducing-linq-languageintegrated.html' title='Introducing LINQ: Language‐Integrated Query'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-1289294142848822540</id><published>2010-02-10T19:38:00.000-08:00</published><updated>2010-02-10T19:40:57.849-08:00</updated><title type='text'>How to Bind a GridView Control to XML in ASP.NET</title><content type='html'>In this example, your XML content is assumed to be ready and well formatted. To be compatible with a GridView, the XML document has to have a database-like format (table and records):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;countries&gt;&lt;br /&gt;  &lt;country&gt;&lt;br /&gt;    &lt;name&gt;ANGOLA&lt;/name&gt;&lt;code&gt;24&lt;/code&gt;&lt;size&gt;1345 amp&lt;/size&gt;&lt;br /&gt;  &lt;/country&gt;&lt;br /&gt;  &lt;country&gt;&lt;br /&gt;    &lt;name&gt;BENIN&lt;/name&gt;&lt;code&gt;204&lt;/code&gt;&lt;size&gt;435 amp&lt;/size&gt;&lt;br /&gt;  &lt;/country&gt;&lt;br /&gt;&lt;/countries&gt;&lt;br /&gt;&lt;br /&gt;   1. Drag a GridView component from the Toolbox.&lt;br /&gt;   2. Add to your GridView a PreRender event.&lt;br /&gt;   3. Write your code (see below) to bind a DataSet to the GridView.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public partial class _Default : System.Web.UI.Page&lt;br /&gt;{&lt;br /&gt; protected void MyGridView_PreRender(object sender, EventArgs e)&lt;br /&gt; {&lt;br /&gt;  // Creates a DataSet and loads it with an Xml Content&lt;br /&gt;  DataSet aDataSet = new DataSet();&lt;br /&gt;  aDataSet.ReadXml(new StringReader(aXmlDoc.OuterXml));&lt;br /&gt;&lt;br /&gt;  // Bind the DataSet to the grid view&lt;br /&gt;  GridView gv = (GridView)sender;&lt;br /&gt;  gv.DataSource = aDataSet;&lt;br /&gt;  gv.DataBind();&lt;br /&gt; }&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-1289294142848822540?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/1289294142848822540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/how-to-bind-gridview-control-to-xml-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1289294142848822540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1289294142848822540'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/how-to-bind-gridview-control-to-xml-in.html' title='How to Bind a GridView Control to XML in ASP.NET'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-5316431649206073729</id><published>2010-02-10T19:35:00.000-08:00</published><updated>2010-02-10T19:38:16.911-08:00</updated><title type='text'>AutoComplete TextBox</title><content type='html'>Introduction&lt;br /&gt;&lt;br /&gt;I was in need of a simple auto-completing textbox for a project I was working on at work when I realized that there were really not a whole lot of good choices for this. Many of them derive from a combo box which will not work properly for a dropdown list that continues to filter out items as you continue to type. This is my first article, so any feedback is welcome.&lt;br /&gt;Using the textbox&lt;br /&gt;&lt;br /&gt;Using the text box is simple, just add some AutoCompleteEntry items to the textbox:&lt;br /&gt;&lt;br /&gt;The Items collection holds objects that implement the IAutoCompleteEntry interface. This allows you to use the AutoCompleteTextBox for a wide range of purposes. The IAutoCompleteEntry objects publish a list of string objects that are used to match with the user input. The popup list displays the result of a call to the object's ToString() method.&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt; // Add some sample auto complete entry items...&lt;br /&gt;&lt;br /&gt; this.coolTextBox1.Items.Add(new AutoCompleteEntry("Phoenix, Az", "Phoenix, Az",&lt;br /&gt;                                                   "Az", "PHX"));&lt;br /&gt; this.coolTextBox1.Items.Add(new AutoCompleteEntry("Tempe, Az", "Tempe, Az","Az",&lt;br /&gt;                                                   "TPE"));&lt;br /&gt; this.coolTextBox1.Items.Add(new AutoCompleteEntry("Chandler, Az", &lt;br /&gt;                                                   "Chandler, Az", "Az", "CHA"));&lt;br /&gt; this.coolTextBox1.Items.Add(new AutoCompleteEntry("Boxford, Ma", "Boxford, Ma",&lt;br /&gt;                                                   "Ma", "BXF"));&lt;br /&gt; this.coolTextBox1.Items.Add(new AutoCompleteEntry("Topsfield, Ma", &lt;br /&gt;                                                   "Topsfield, Ma", "Ma", "TPF"));&lt;br /&gt; this.coolTextBox1.Items.Add(new AutoCompleteEntry("Danvers, Ma", "Danvers, Ma", &lt;br /&gt;                                                   "Ma", "DNV"));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note: I created a control called CoolTextBox that is a composite control with an AutoCompleteTextBox in it. all it really does is add a cool looking border to the textbox. I am using the CooltextBox in the demo project.&lt;br /&gt;Design&lt;br /&gt;&lt;br /&gt;So I decided to use a simple textbox and handle key press events to show a popup window that has a list in it. The list will be filtered to show only items that match the text in the textbox.&lt;br /&gt;Problems&lt;br /&gt;&lt;br /&gt;The problem with this is that there is no easy way to get the popup window to behave like any normal person would expect it to. It is easy to get the popup to show, but we need to keep the focus on the textbox, update the list on the popup, and even send some keystroke events over to the popup. Also, we need to hide the popup anytime the user clicks the mouse outside of the popup or outside the textbox (I know this sounds like it should be simple).&lt;br /&gt;Implementation&lt;br /&gt;Controlling the popup&lt;br /&gt;&lt;br /&gt;I like to make controls as generic and customizable as possible. I like my auto-complete text box to popup after I type a couple characters, or if I press the Control+Space key combination. Someone else may have a completely different set of preferences, so I decided to control the popup events through a customizable set of AutoCompleteTrigger objects. Here is how the default behavior is set up (the ones that say "Consume" prevent further processing of the key press):&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt; // Add default triggers.&lt;br /&gt;&lt;br /&gt; this.triggers.Add(new TextLengthTrigger(2));&lt;br /&gt; this.triggers.Add(new ShortCutTrigger(Keys.Enter, TriggerState.SelectAndConsume));&lt;br /&gt; this.triggers.Add(new ShortCutTrigger(Keys.Tab, TriggerState.Select));&lt;br /&gt; this.triggers.Add(new ShortCutTrigger(Keys.Control | Keys.Space, TriggerState&lt;br /&gt;                                      .ShowAndConsume));&lt;br /&gt; this.triggers.Add(new ShortCutTrigger(Keys.Escape, TriggerState.HideAndConsume));&lt;br /&gt;&lt;br /&gt;When to close the popup&lt;br /&gt;&lt;br /&gt;The popup should close under any of the following circumstances:&lt;br /&gt;&lt;br /&gt;   1. The user clicks on an item in the list&lt;br /&gt;   2. Any of the triggers evaluate to&lt;br /&gt;         1. TriggerState.Select&lt;br /&gt;         2. TriggerState.SelectAndConsume&lt;br /&gt;         3. TriggerState.Hide&lt;br /&gt;         4. TriggerState.HideAndConsume&lt;br /&gt;   3. The user clicks anywhere other than the popup or the text box.&lt;br /&gt;&lt;br /&gt;Scenarios 1 and 2 are fairly easy, so I won't delve into that here. You can check out the source code if you are interested. Its the 3rd scenario that really turned out to be a challenge.&lt;br /&gt;Handling mouse clicks&lt;br /&gt;&lt;br /&gt;So there are several places we need to hook in to determine if the mouse was clicked outside of the text box or the popup.&lt;br /&gt;&lt;br /&gt;We need to catch the OnLostFocus of the text box, as well as the Deactivate event of the popup.&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt; protected override void OnLostFocus(EventArgs e)&lt;br /&gt; {&lt;br /&gt;  base.OnLostFocus (e);&lt;br /&gt;  if (!(this.Focused || this.popup.Focused || this.list.Focused))&lt;br /&gt;  {&lt;br /&gt;   this.HideList();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void Popup_Deactivate(object sender, EventArgs e)&lt;br /&gt; {&lt;br /&gt;  if (!(this.Focused || this.popup.Focused || this.list.Focused))&lt;br /&gt;  {&lt;br /&gt;   this.HideList();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;Those are the easy ones. Now we need to trap all mouse events that go to the form that the textbox lives on and its child controls. This is a little more difficult. o do this I used a NativeWindow as a base class for my mouse hook. I then listened for any mouse click event. If the mouse click occurred within the bounding box of the text box, then the popup remains visible. Otherwise, we should hide the popup.&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;  /// &lt;summary&gt;&lt;br /&gt;&lt;br /&gt;  /// This is the class we will use to hook mouse events.&lt;br /&gt;&lt;br /&gt;  /// &lt;/summary&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  private class WinHook : NativeWindow&lt;br /&gt;  {&lt;br /&gt;   private AutoCompleteTextBox tb;&lt;br /&gt;   /// &lt;summary&gt;&lt;br /&gt;&lt;br /&gt;   /// Initializes a new instance of &lt;see cref="WinHook"/&gt;&lt;br /&gt;&lt;br /&gt;   /// &lt;/summary&gt;&lt;br /&gt;&lt;br /&gt;   /// &lt;param name="tbox"&gt;The &lt;see cref="AutoCompleteTextBox"/&gt; the hook is running &lt;br /&gt;&lt;br /&gt;   /// for.&lt;/param&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   public WinHook(AutoCompleteTextBox tbox)&lt;br /&gt;   {&lt;br /&gt;    this.tb = tbox;&lt;br /&gt;   }&lt;br /&gt;   /// &lt;summary&gt;&lt;br /&gt;&lt;br /&gt;   /// Look for any kind of mouse activity that is not in the&lt;br /&gt;&lt;br /&gt;   /// text box itself, and hide the popup if it is visible.&lt;br /&gt;&lt;br /&gt;   /// &lt;/summary&gt;&lt;br /&gt;&lt;br /&gt;   /// &lt;param name="m"&gt;&lt;/param&gt;&lt;br /&gt;&lt;br /&gt;   protected override void WndProc(ref Message m)&lt;br /&gt;   {&lt;br /&gt;    switch (m.Msg)&lt;br /&gt;    {&lt;br /&gt;     case Win32.Messages.WM_LBUTTONDOWN:&lt;br /&gt;     case Win32.Messages.WM_LBUTTONDBLCLK:&lt;br /&gt;     case Win32.Messages.WM_MBUTTONDOWN:&lt;br /&gt;     case Win32.Messages.WM_MBUTTONDBLCLK:&lt;br /&gt;     case Win32.Messages.WM_RBUTTONDOWN:&lt;br /&gt;     case Win32.Messages.WM_RBUTTONDBLCLK:&lt;br /&gt;     case Win32.Messages.WM_NCLBUTTONDOWN:&lt;br /&gt;     case Win32.Messages.WM_NCMBUTTONDOWN:&lt;br /&gt;     case Win32.Messages.WM_NCRBUTTONDOWN:&lt;br /&gt;     {&lt;br /&gt;      // Lets check to see where the event took place&lt;br /&gt;&lt;br /&gt;      Form form = tb.FindForm();&lt;br /&gt;      Point p = form.PointToScreen(new Point((int)m.LParam));&lt;br /&gt;      Point p2 = tb.PointToScreen(new Point(0, 0));&lt;br /&gt;      Rectangle rect = new Rectangle(p2, tb.Size);&lt;br /&gt;      // Hide the popup if it is not in the text box&lt;br /&gt;&lt;br /&gt;      if (!rect.Contains(p))&lt;br /&gt;      {&lt;br /&gt;       tb.HideList();&lt;br /&gt;      }&lt;br /&gt;     } break;&lt;br /&gt;     case Win32.Messages.WM_SIZE:&lt;br /&gt;     case Win32.Messages.WM_MOVE:&lt;br /&gt;     {&lt;br /&gt;      tb.HideList();&lt;br /&gt;     } break;&lt;br /&gt;     // This is the message that gets sent when a child control gets activity&lt;br /&gt;&lt;br /&gt;     case Win32.Messages.WM_PARENTNOTIFY:&lt;br /&gt;     {&lt;br /&gt;      switch ((int)m.WParam)&lt;br /&gt;      {&lt;br /&gt;       case Win32.Messages.WM_LBUTTONDOWN:&lt;br /&gt;       case Win32.Messages.WM_LBUTTONDBLCLK:&lt;br /&gt;       case Win32.Messages.WM_MBUTTONDOWN:&lt;br /&gt;       case Win32.Messages.WM_MBUTTONDBLCLK:&lt;br /&gt;       case Win32.Messages.WM_RBUTTONDOWN:&lt;br /&gt;       case Win32.Messages.WM_RBUTTONDBLCLK:&lt;br /&gt;       case Win32.Messages.WM_NCLBUTTONDOWN:&lt;br /&gt;       case Win32.Messages.WM_NCMBUTTONDOWN:&lt;br /&gt;       case Win32.Messages.WM_NCRBUTTONDOWN:&lt;br /&gt;       {&lt;br /&gt;        // Same thing as before&lt;br /&gt;&lt;br /&gt;        Form form = tb.FindForm();&lt;br /&gt;        Point p = form.PointToScreen(new Point((int)m.LParam));&lt;br /&gt;        Point p2 = tb.PointToScreen(new Point(0, 0));&lt;br /&gt;        Rectangle rect = new Rectangle(p2, tb.Size);&lt;br /&gt;        if (!rect.Contains(p))&lt;br /&gt;        {&lt;br /&gt;         tb.HideList();&lt;br /&gt;        }&lt;br /&gt;       } break;&lt;br /&gt;      }&lt;br /&gt;     } break;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    base.WndProc (ref m);&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;Conclusion&lt;br /&gt;&lt;br /&gt;While there are more details as to how the whole thing goes together, they are alot more straight forward. I feel this is a viable solution for an Auto-Complete TextBox and I hope you find it interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-5316431649206073729?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/5316431649206073729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/autocomplete-textbox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5316431649206073729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5316431649206073729'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/autocomplete-textbox.html' title='AutoComplete TextBox'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-5582389513529370492</id><published>2010-02-10T19:33:00.000-08:00</published><updated>2010-02-10T19:35:54.071-08:00</updated><title type='text'>Sending and playing microphone audio over network</title><content type='html'>Introduction&lt;br /&gt;&lt;br /&gt;This example shows you how to receive data from a microphone and stream it over UDP to another computer. The example application can act like a direct phone, if both endpoints listen for data and send microphone data to each other. One would probably suspect that no source code exists for that, but of course it does. I hate those who will do commercial advertising. There is also a second related project what will contain a UDP server that we need to send/receive audio and compress it with g711 codec.Though only UDP is not the best way to transport audio data, RTP is the right way to go. RTP adds quality of service to transported audio, you can see how many packets are lost and can even arrange disordered packets. I will try to add an RTP example soon, so be calm, it's under way. There are some similar example applications, but most of them aren't well commented and missing some parts, so I will try to fill this part.&lt;br /&gt;&lt;br /&gt;The package contains:&lt;br /&gt;&lt;br /&gt;    * LumiSoft.Media - Audio related API (Included in example app)&lt;br /&gt;    * LumiSoft.Net - UDP server, G711 codec&lt;br /&gt;    * Example Application&lt;br /&gt;&lt;br /&gt;Using the code&lt;br /&gt;&lt;br /&gt;    * WaveIn - class provides a simple way to receive audio from a microphone.&lt;br /&gt;      Actually all what you need to do is:&lt;br /&gt;      WavIn.Devices - returns all available input devices from where we can get data.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      /// &lt;summary&gt;&lt;br /&gt;&lt;br /&gt;      /// Application main class.&lt;br /&gt;&lt;br /&gt;      /// &lt;/summary&gt;&lt;br /&gt;&lt;br /&gt;      public class Test&lt;br /&gt;      {&lt;br /&gt;          private WavIn m_pSoundReceiver = null;&lt;br /&gt;&lt;br /&gt;          /// &lt;summary&gt;&lt;br /&gt;&lt;br /&gt;          /// Default constructor.&lt;br /&gt;&lt;br /&gt;          /// &lt;/summary&gt;&lt;br /&gt;&lt;br /&gt;          public Test()&lt;br /&gt;          {&lt;br /&gt;              // G711 needs 8KHZ 16 bit 1 channel audio, &lt;br /&gt;&lt;br /&gt;              // 400kb buffer gives us 25ms audio frame.&lt;br /&gt;&lt;br /&gt;              m_pSoundReceiver = new WavIn(WavIn.Devices[0],8000,16,1,400);&lt;br /&gt;              m_pSoundReceiver.BufferFull += new BufferFullHandler &lt;br /&gt;                                               (m_pSoundReceiver_BufferFull);&lt;br /&gt;              m_pSoundReceiver.Start();&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          /// &lt;summary&gt;&lt;br /&gt;&lt;br /&gt;          /// This method is called when recording buffer is full &lt;br /&gt;&lt;br /&gt;          /// and we need to process it.&lt;br /&gt;&lt;br /&gt;          /// &lt;/summary&gt;&lt;br /&gt;&lt;br /&gt;          /// &lt;param name="buffer"&gt;Recorded data.&lt;/param&gt;&lt;br /&gt;&lt;br /&gt;          private void m_pSoundReceiver_BufferFull(byte[] buffer)&lt;br /&gt;          {&lt;br /&gt;              // Just store audio data or stream it over the network ... &lt;br /&gt;&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;    * WaveOut - class provides methods for playing out streaming data.&lt;br /&gt;      The only thing you need to do is just call waveoutInstance.Play method.&lt;br /&gt;      In my opinion, the whole example application has been coded well enough, so dig into the code.&lt;br /&gt;&lt;br /&gt;      Note: Sound quality depends on network delay jittering, if there will be too big a variance in delays, voice will have holes in it. In addition, UDP packet loss and disordered packets will affect it too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-5582389513529370492?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/5582389513529370492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/sending-and-playing-microphone-audio.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5582389513529370492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5582389513529370492'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/sending-and-playing-microphone-audio.html' title='Sending and playing microphone audio over network'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-1766315865176933955</id><published>2010-02-05T20:35:00.000-08:00</published><updated>2010-02-05T20:36:29.113-08:00</updated><title type='text'>Loading image files from a database, using ADO</title><content type='html'>Introduction&lt;br /&gt;Putting and retrieving image files in to a database, is not a simple task. I you want to look on the Internet for such a sample, you will be surprised that there is no C++ sample for that. There is only information, that you have to use the Safearray, SetChunk, and GetChunk methods.&lt;br /&gt;&lt;br /&gt;This article will show how you can put image files in to a database via ADO, as well as how you can retrieve them. With this example, you can use any file format such as Word, Excel etc., not just image file formats.&lt;br /&gt;&lt;br /&gt;Implementation&lt;br /&gt;The example contains two methods for putting and retrieving image files to and from a database. The first method retrieves data from the database, create a file in a temporary directory, and puts the data into a file created. The parameter strImageName is the name of the file that will be created. The second parameter indicates the ADO field object containing the image data.&lt;br /&gt;&lt;br /&gt;The following code sample shows the implementation:&lt;br /&gt;&lt;br /&gt; Collapse Copy Code&lt;br /&gt;CString CADOImageDBDlg::GetImageFromADO(CString &lt;br /&gt;                  strImageName, FieldPtr pField)&lt;br /&gt;{&lt;br /&gt;    //Creating temp file&lt;br /&gt;    char tmpPath[_MAX_PATH+1];&lt;br /&gt;    GetTempPath(_MAX_PATH,tmpPath);&lt;br /&gt;    strImageName.Insert(0,tmpPath);&lt;br /&gt;    CFile outFile(strImageName, &lt;br /&gt;      CFile::modeCreate|CFile::modeWrite);&lt;br /&gt; &lt;br /&gt;    //Helper variable for retrieving image data&lt;br /&gt;    unsigned char* lpData = NULL;&lt;br /&gt;    long lngOffSet = 0;&lt;br /&gt;    long lngSize=pField-&gt;ActualSize;&lt;br /&gt;    const long ChunkSize=50;     &lt;br /&gt;    _variant_t varChunk;    &lt;br /&gt;    UCHAR chData;&lt;br /&gt;    HRESULT hr;&lt;br /&gt;    long lBytesCopied = 0;&lt;br /&gt;    lpData=new unsigned char [lngSize];&lt;br /&gt; &lt;br /&gt;    //Retrieveing data from vararray&lt;br /&gt;    while(lngOffSet &lt; lngSize)&lt;br /&gt;    { &lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            //Get 50 size long chunk from database&lt;br /&gt;            varChunk = pField-&gt;GetChunk(ChunkSize);&lt;br /&gt;     &lt;br /&gt;            //putting chunk in to safe array&lt;br /&gt;            for(long lIndex = 0; lIndex &lt;= &lt;br /&gt;                    (ChunkSize - 1); lIndex++)&lt;br /&gt;            {&lt;br /&gt;                hr= &lt;br /&gt;                  SafeArrayGetElement(varChunk.parray, &lt;br /&gt;                  &amp;lIndex, &amp;chData);&lt;br /&gt;                if(SUCCEEDED(hr))&lt;br /&gt;                {&lt;br /&gt;                    ((UCHAR*)lpData)[lBytesCopied] = chData;&lt;br /&gt;                    lBytesCopied++;&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                    break;&lt;br /&gt;            }&lt;br /&gt;            lngOffSet += ChunkSize;&lt;br /&gt;        }&lt;br /&gt;        catch(_com_error &amp;e)&lt;br /&gt;        {&lt;br /&gt;            dump_com_error(e);&lt;br /&gt;            return FALSE;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    //&lt;br /&gt;    LPSTR buffer = (LPSTR)GlobalLock(lpData);&lt;br /&gt;    // write data in to file&lt;br /&gt;    outFile.Write(lpData,lngSize);&lt;br /&gt;    &lt;br /&gt;    // free reserved data&lt;br /&gt;    GlobalUnlock(lpData);&lt;br /&gt;    delete lpData;&lt;br /&gt;     &lt;br /&gt;    //Return full path file&lt;br /&gt;    return strImageName;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;bool CADOImageDBDlg::PutImageInADO(CString &lt;br /&gt;           strFilePath,FieldPtr pFileData)&lt;br /&gt;{&lt;br /&gt;    //Opent File&lt;br /&gt;    CFile fileImage;&lt;br /&gt;    CFileStatus fileStatus;&lt;br /&gt;    fileImage.Open(strFilePath, CFile::modeRead);&lt;br /&gt;    fileImage.GetStatus(fileStatus);&lt;br /&gt;&lt;br /&gt;    //Alocating memory for data &lt;br /&gt;    ULONG nBytes = (ULONG)fileStatus.m_size;&lt;br /&gt;    HGLOBAL hGlobal = GlobalAlloc(GPTR,nBytes);&lt;br /&gt;    LPVOID lpData = GlobalLock(hGlobal);&lt;br /&gt;&lt;br /&gt;    //Putting data in to file&lt;br /&gt;    fileImage.Read(lpData,nBytes);&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;    HRESULT hr;&lt;br /&gt;    _variant_t varChunk;&lt;br /&gt;    long lngOffset = 0;&lt;br /&gt;    UCHAR chData;&lt;br /&gt;    SAFEARRAY FAR *psa = NULL;&lt;br /&gt;    SAFEARRAYBOUND rgsabound[1];&lt;br /&gt; &lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        //Create a safe array to &lt;br /&gt;        //store the array of BYTES &lt;br /&gt;        rgsabound[0].lLbound = 0;&lt;br /&gt;        rgsabound[0].cElements = nBytes;&lt;br /&gt;        psa = SafeArrayCreate(VT_UI1,1,rgsabound);&lt;br /&gt;         &lt;br /&gt;        while(lngOffset &lt; (long)nBytes)&lt;br /&gt;        {&lt;br /&gt;            chData      = ((UCHAR*)lpData)[lngOffset];&lt;br /&gt;            hr = SafeArrayPutElement(psa, &lt;br /&gt;                       &amp;lngOffset, &amp;chData);&lt;br /&gt;             &lt;br /&gt;            if(hr!=S_OK) &lt;br /&gt;            return false;&lt;br /&gt;             &lt;br /&gt;            lngOffset++;&lt;br /&gt;        }&lt;br /&gt;        lngOffset = 0;&lt;br /&gt; &lt;br /&gt;        //Assign the Safe array  to a variant. &lt;br /&gt;        varChunk.vt = VT_ARRAY|VT_UI1;&lt;br /&gt;        varChunk.parray = psa;&lt;br /&gt;         &lt;br /&gt;        hr = pFileData-&gt;AppendChunk(varChunk);&lt;br /&gt; &lt;br /&gt;        if(hr!=S_OK) &lt;br /&gt;            return false;&lt;br /&gt;    }&lt;br /&gt;    catch(_com_error &amp;e)&lt;br /&gt;    {&lt;br /&gt;        dump_com_error(e);&lt;br /&gt;        return FALSE;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    //Free memory&lt;br /&gt;    GlobalUnlock(lpData);&lt;br /&gt;    return true;&lt;br /&gt;}For image display, I created a class which wraps the freeimage library.&lt;br /&gt;&lt;br /&gt;Update history&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-1766315865176933955?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/1766315865176933955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/loading-image-files-from-database-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1766315865176933955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/1766315865176933955'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/loading-image-files-from-database-using.html' title='Loading image files from a database, using ADO'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-3276872304151496077</id><published>2010-02-05T20:30:00.000-08:00</published><updated>2010-02-05T20:32:59.929-08:00</updated><title type='text'>Sql bulk copy with c# .net</title><content type='html'>Introduction&lt;br /&gt;Programmers usually need to transfer production data for testing or analyzing. The simplest way to copy lots of data from any resources to SQL Server is BulkCopying. .NET Framework 2.0 contains a class in ADO.NET "System.Data.SqlClient" namespace: SqlBulkCopy. The bulk copy operation usually has two separated phases. &lt;br /&gt;&lt;br /&gt;In the first phase you get the source data. The source could be various data platforms such as Access, Excel, SQL.. You must get the source data in your code wrapping it in a DataTable, or any DataReader class which implements IDataReader. After that, in the second phase, you must connect the target SQL Database and perform the bulk copy operation. &lt;br /&gt;&lt;br /&gt;The bulk copy operation in .Net is a very fast way to copy large amount of data somewhere to SQL Server. The reason for that is the Bulkcopy Sql Server mechanism. Inserting all data row by row, one after the other is a very time and system resources consuming. But the bulkcopy mechanism process all data at once. So the data inserting becomes very fast. &lt;br /&gt;&lt;br /&gt;Solution walkthrough&lt;br /&gt;While you are programming for bulk copy, first open a connection for the source data. In this sample we are connecting a SQL Server named SQLProduction. We are using SqlConnectionStringBuilder to build our connection string.&lt;br /&gt;&lt;br /&gt; Collapse Copy Code&lt;br /&gt;// Establishing connection&lt;br /&gt;SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder(); &lt;br /&gt;cb.DataSource = "SQLProduction"; &lt;br /&gt;cb.InitialCatalog = "Sales"; &lt;br /&gt;cb.IntegratedSecurity = true;&lt;br /&gt;SqlConnection cnn = new SqlConnection(cb.ConnectionString);  &lt;br /&gt;Then we are retrieving data from the source with SqlCommand and SqlDataReader classes.  &lt;br /&gt;&lt;br /&gt; Collapse Copy Code&lt;br /&gt;// Getting source data&lt;br /&gt;SqlCommand cmd = new SqlCommand("SELECT * FROM PendingOrders",cnn); &lt;br /&gt;cnn.Open(); &lt;br /&gt;SqlDataReader rdr = cmd.ExecuteReader(); &lt;br /&gt;Now we have a data in rdr variable. It's time to initialize a SqlBulkCopy object and copy the data. The SqlBulkCopy class needs a connection to copy data into a Sql server. You can establish a second connection explicitly or the class will do it for you. We are using the second alternative with creating a SqlBulkCopy object. We are passing a connection string as a parameter in constructor method.&lt;br /&gt;&lt;br /&gt; Collapse Copy Code&lt;br /&gt;// Initializing an SqlBulkCopy object&lt;br /&gt;SqlBulkCopy sbc = new SqlBulkCopy("server=.;database=ProductionTest;" +                                  "Integrated Security=SSPI"); OK. The sbc object is ready to copy. Now you must tell the object the destination table name, start the copying process calling WriteToServer method and pass the method the SqlDataReader variable rdr as parameter.&lt;br /&gt;&lt;br /&gt; Collapse Copy Code&lt;br /&gt;// Copying data to destination&lt;br /&gt;sbc.DestinationTableName = "Temp"; &lt;br /&gt;sbc.WriteToServer(rdr); At the end, close all SqlConnection, SqlDataReader and SqlBulkCopy objects.&lt;br /&gt;&lt;br /&gt; Collapse Copy Code&lt;br /&gt;// Closing connection and the others&lt;br /&gt;sbc.Close(); &lt;br /&gt;rdr.Close(); &lt;br /&gt;cnn.Close(); That's all. Just a few lines and in a few seconds...&lt;br /&gt;&lt;br /&gt; Collapse Copy Code&lt;br /&gt;// Establishing connection&lt;br /&gt;SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder(); &lt;br /&gt;cb.DataSource = "SQLProduction"; &lt;br /&gt;cb.InitialCatalog = "Sales"; &lt;br /&gt;cb.IntegratedSecurity = true;&lt;br /&gt;SqlConnection cnn = new SqlConnection(cb.ConnectionString);  &lt;br /&gt;&lt;br /&gt;// Getting source data&lt;br /&gt;SqlCommand cmd = new SqlCommand("SELECT * FROM PendingOrders",cnn); &lt;br /&gt;cnn.Open(); &lt;br /&gt;SqlDataReader rdr = cmd.ExecuteReader(); &lt;br /&gt;&lt;br /&gt;// Initializing an SqlBulkCopy object&lt;br /&gt;SqlBulkCopy sbc = new SqlBulkCopy("server=.;database=ProductionTest;" +                                  "Integrated Security=SSPI"); &lt;br /&gt;&lt;br /&gt;// Copying data to destination&lt;br /&gt;sbc.DestinationTableName = "Temp"; &lt;br /&gt;sbc.WriteToServer(rdr); &lt;br /&gt;&lt;br /&gt;// Closing connection and the others&lt;br /&gt;sbc.Close(); &lt;br /&gt;rdr.Close(); &lt;br /&gt;cnn.Close();&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-3276872304151496077?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/3276872304151496077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/sql-bulk-copy-with-c-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3276872304151496077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3276872304151496077'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/sql-bulk-copy-with-c-net.html' title='Sql bulk copy with c# .net'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-7866557403921263329</id><published>2010-02-05T02:15:00.000-08:00</published><updated>2010-02-05T02:16:05.220-08:00</updated><title type='text'>Google Earth network link</title><content type='html'>Introduction&lt;br /&gt;&lt;br /&gt;This article aims to show the creation of Network Links for Google Earth.&lt;br /&gt;The Code Source&lt;br /&gt;&lt;br /&gt;Create a new ASP.NET Web application and upon Page_Load, copy and paste this code, or download the source code.&lt;br /&gt;Grid Creation: Creating the Constructor for the Grid&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;Imports System.Xml&lt;br /&gt;Partial Public Class _Default&lt;br /&gt;    Inherits System.Web.UI.Page&lt;br /&gt;    Protected Sub Page_Load(ByVal sender As Object,&lt;br /&gt;            ByVal e As System.EventArgs) Handles Me.Load&lt;br /&gt;        Me.Response.Clear()&lt;br /&gt;        Me.Response.ContentType = "application/vnd.google-earth.kml+xml"&lt;br /&gt;        'Para ver o documento XML&lt;br /&gt;        'For view XML document&lt;br /&gt;        'My.Response.ContentType = "plain/text"&lt;br /&gt;        Me.Response.ContentEncoding = System.Text.Encoding.UTF8&lt;br /&gt;        Dim stream As New System.IO.MemoryStream&lt;br /&gt;        Dim XMLwrite As New XmlTextWriter(stream, System.Text.Encoding.UTF8)&lt;br /&gt;        XMLwrite.WriteStartDocument()&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteStartElement("kml")&lt;br /&gt;        XMLwrite.WriteAttributeString("xmlns",&lt;br /&gt;           "http://earth.google.com/kml/2.0")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        '&lt;Document&gt;&lt;br /&gt;        XMLwrite.WriteStartElement("Document")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteElementString("name", "Signal Control")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        '&lt;Placemark&gt;&lt;br /&gt;        XMLwrite.WriteStartElement("Placemark")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteElementString("description", "MY DESCRIPTION/MINHA DESCRIÇÃO")&lt;br /&gt;        XMLwrite.WriteElementString("name", "MY NAME/MEU NOME")&lt;br /&gt;        XMLwrite.WriteStartElement("LookAt")&lt;br /&gt;        XMLwrite.WriteElementString("longitude", "MY LONGITUDE/MINHA LONGITUDE")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteElementString("latitude", "MY LATITUDE/MINHA LATITUDE")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteEndElement()&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteElementString("visibility", "1")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        '&lt;Style&gt;&lt;br /&gt;        XMLwrite.WriteStartElement("Style")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        '&lt;IconStyle&gt;&lt;br /&gt;        XMLwrite.WriteStartElement("IconStyle")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        '&lt;Icon&gt;&lt;br /&gt;        XMLwrite.WriteStartElement("Icon")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        'Meu ícone, mudar este diretório&lt;br /&gt;        'My Icon, change this directory&lt;br /&gt;        XMLwrite.WriteElementString("href", "C:\Code_Project\01.ico")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteElementString("w", "-1")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteElementString("h", "-1")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteEndElement()&lt;br /&gt;        '&lt;/Icon&gt;&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteEndElement()&lt;br /&gt;        '&lt;/IconStyle&gt;&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteEndElement()&lt;br /&gt;        '&lt;/Style&gt;&lt;br /&gt;        '&lt;Point&gt;&lt;br /&gt;        XMLwrite.WriteStartElement("Point")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        'Minhas coordenadas, mudar aqui&lt;br /&gt;        'My Coordinates, change aqui&lt;br /&gt;        XMLwrite.WriteElementString("coordinates", &lt;br /&gt;            "-25.4942072754", "-49.5426559491",&lt;br /&gt;            "50")&lt;br /&gt;        XMLwrite.WriteWhitespace(Environment.NewLine)&lt;br /&gt;        XMLwrite.WriteEndElement()&lt;br /&gt;        XMLwrite.WriteEndElement()&lt;br /&gt;        '&lt;/Point&gt;'Fim do XML&lt;br /&gt;        'Finish XML&lt;br /&gt;        XMLwrite.WriteEndDocument()&lt;br /&gt;        XMLwrite.Flush()&lt;br /&gt;        Dim reader As IO.StreamReader&lt;br /&gt;        stream.Position = 0&lt;br /&gt;        reader = New IO.StreamReader(stream)&lt;br /&gt;        Dim bytes() As Byte = System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd())&lt;br /&gt;        Me.Response.BinaryWrite(bytes)&lt;br /&gt;        Me.Response.End()&lt;br /&gt;    End Sub&lt;br /&gt;End Class &lt;br /&gt;&lt;br /&gt;Points of Interest&lt;br /&gt;&lt;br /&gt;Go to places on Google Earth and click Add Network Link.&lt;br /&gt;&lt;br /&gt;Screenshot - image002.jpg&lt;br /&gt;&lt;br /&gt;Screenshot - image003.jpg&lt;br /&gt;&lt;br /&gt;After compiling the project, this icon will arise:&lt;br /&gt;&lt;br /&gt;Screenshot - image004.jpg&lt;br /&gt;&lt;br /&gt;My link is created:&lt;br /&gt;&lt;br /&gt;Screenshot - image005.jpg&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-7866557403921263329?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/7866557403921263329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/google-earth-network-link.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/7866557403921263329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/7866557403921263329'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/google-earth-network-link.html' title='Google Earth network link'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-3731598866235249865</id><published>2010-02-05T02:11:00.000-08:00</published><updated>2010-02-05T02:12:12.423-08:00</updated><title type='text'>Integrate webcam with a .net application</title><content type='html'>Introduction&lt;br /&gt;&lt;br /&gt;Webcam is a Simple Object Access Protocol (SOAP) project that will permit client's software to get, from a Web Service, JPEG pictures captured by a Webcam. It is my first step experiment in the world of SOAP after several projects using COM/DCOM and ATL.&lt;br /&gt;&lt;br /&gt;The project is split in three parts:&lt;br /&gt;&lt;br /&gt;    * Server: Active Template Library Server capturing a picture from the Webcam.&lt;br /&gt;    * Web Service: Generated with WSDL Generator from Microsoft�.&lt;br /&gt;    * Client: ActiveX client connecting to Webcam SOAP Server getting pictures and displaying them.&lt;br /&gt;&lt;br /&gt;Server&lt;br /&gt;&lt;br /&gt;We use Visual C++ and the Active Template Library (ATL) object Wizard to create a Simple COM object, called Camera. It handles the grabbing of the picture and the JPEG compression.&lt;br /&gt;&lt;br /&gt;The jpeg compression is achieved with Intel� JPEG Library v1.5. Get it here. You may use other libraries, like IJG JPEG LIBRARY, by using the abstract base class CPicturePacker.&lt;br /&gt;&lt;br /&gt;Camera handling is done using Microsoft� Video for Windows� (VFW). Get more information on MSDN / Platform SDK Documentation / Graphics and Multimedia Services / Windows Multimedia / Video Capture.&lt;br /&gt;&lt;br /&gt;Trick: VFW needs a handler on a window to attach the camera driver to. As we chose to create a Simple COM object we do not have access to any window handler. Calling GetDesktopWindow() got us one.&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;    // Don't have access to the container's window so just use the desktop.&lt;br /&gt;&lt;br /&gt;    // RMK: If the desktop is not at least 24bits colors, then the grab will&lt;br /&gt;&lt;br /&gt;    //      fail&lt;br /&gt;&lt;br /&gt;    HWND hWnd = ::GetDesktopWindow();&lt;br /&gt;&lt;br /&gt;    if ( hWnd )&lt;br /&gt;    { ...&lt;br /&gt;&lt;br /&gt;All functionalities needed to grab a picture on a Webcam are done in the class CWebCam. For example the method GrabFrame:&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;    bool CWebCam::GrabFrame( CPicturePacker * pPacker,&lt;br /&gt;                             unsigned char  ** ppPackedPicture,&lt;br /&gt;                             unsigned long  * pnPackedPictureBytes )&lt;br /&gt;&lt;br /&gt;Use a reference to a CPicturePacker base class to pack the original picture's bits, permitting to extend the packing to whatever format you want, as mentioned before. In this sample I have written the class CIntelJpegPacker inheriting from CPicturePacker and using the Intel� JPEG Library v1.5 to pack the picture grabbed. You may consider using GDI+ for example to do the same.&lt;br /&gt;&lt;br /&gt;The rest of the source is dealing with COM and is nothing special.&lt;br /&gt;Server Interface&lt;br /&gt;&lt;br /&gt;Our server needs to achieve two simple operations: grabbing a picture from a Webcam and compressing it as a JPEG picture according to a compression ratio defined by the caller. This is achieved in the GrabFrame method.&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;HRESULT GrabFrame( [in] short nQuality, &lt;br /&gt;                   [out, retval] SAFEARRAY(unsigned char) * ppGrabbedPicture );&lt;br /&gt;&lt;br /&gt;The input parameter 'nQuality' represents the jpeg compression ratio, from 1 to 99. A value of one meaning lowest quality (highest compression) and a value of ninety-nine meaning highest quality (lowest compression).&lt;br /&gt;&lt;br /&gt;As an output return value the client get the jpeg picture in a SAFEARRAY of unsigned char. We use this data type because it is fully supported by SOAP (See faced problem 1 and 2).&lt;br /&gt;&lt;br /&gt;Our COM object supports the interface IErrorInfo as indicated by the ISupportErrorInfo interface. It permits sending back to the client information about possible issues encountered by the server. The good point is that it is fully automatic for us. Read more about that point in Microsoft SOAP User Guide: "Understanding the SOAP Fault &lt;detail&gt; Contents".&lt;br /&gt;&lt;br /&gt;Before writing your interfaces check out the different types supported by SOAP in "Data Type Mappings" and there equivalence in programming languages. You find them in the Microsoft SOAP User Guide.&lt;br /&gt;Web Service&lt;br /&gt;&lt;br /&gt;We simply use Microsoft WSDL Generator to wrap our COM object, Camera, into a SOAP Web Service.&lt;br /&gt;&lt;br /&gt;On the welcome page click Next.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;On the dialog "Select the COM .dll to analyze":&lt;br /&gt;&lt;br /&gt;Enter the name of your Web Service, i.e. webcam. &lt;br /&gt;&lt;br /&gt;Browse to select your dll.&lt;br /&gt;&lt;br /&gt;Click Next.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;On the dialog "Select the services you would like to expose":&lt;br /&gt;&lt;br /&gt;Expand the list and check the GrabFrame method.&lt;br /&gt;&lt;br /&gt;Click Next.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;On the dialog "SOAP listener information":&lt;br /&gt;&lt;br /&gt;In the URI text box, type the url of your webservice, i.e. http://localhost/webservices/webcam.&lt;br /&gt;&lt;br /&gt;Choose ISAPI Listener type.&lt;br /&gt;&lt;br /&gt;Then select 2001 as XSD Schema Namespace.&lt;br /&gt;&lt;br /&gt;Click Next.&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;On the dialog "Specify the location for the new WSDL and WSML files":&lt;br /&gt;&lt;br /&gt;Select UTF-8 as character set.&lt;br /&gt;&lt;br /&gt;Then select the place you want to store the new files, i.e. c:\inetpub\WebServices\webcam.&lt;br /&gt;&lt;br /&gt;Click Next.&lt;br /&gt;&lt;br /&gt;Click Finish.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Now we have our Web Service! You must also define a Virtual Directory called WebServices in IIS.&lt;br /&gt;In the case you want to change the location of the Web Service you need to change the WSDL file generated by Microsoft WSDL Generator.&lt;br /&gt;Client&lt;br /&gt;&lt;br /&gt;We use Visual C++ and Active Template Library (ATL) object Wizard to create an ActiveX, called Webcam. This ActiveX is the client part of the Web Service Webcam. It is connecting to the Webcam Web Service, receiving back a jpeg picture and displaying it.&lt;br /&gt;&lt;br /&gt;To be able to compile the project you must have installed SOAP Toolkit on your computer. Find it here. For the client you must also have WTL installed. If It is not the case donwload it here.&lt;br /&gt;Client Interface&lt;br /&gt;&lt;br /&gt;To be able to grab a picture on the Webcam Web Service, we need to specify the location of the Web Service and a compression ratio. We define this interface:&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;    HRESULT GrabFrame([in] BSTR strWeb ServiceURL, [in] short nQuality);&lt;br /&gt;&lt;br /&gt;    * Input parameter 'strWeb ServiceURL' represents Web Service's URL.&lt;br /&gt;    * Input parameter 'nQuality' represents the jpeg compression ratio, from 1 to 99. A value of one meaning lowest quality (highest compression) and a value of ninety-nine meaning highest quality (lowest compression).&lt;br /&gt;&lt;br /&gt;If we get an error, we display it in a tooltip. To create and display the tooltip we use Windows Template Library (WTL).&lt;br /&gt;Test&lt;br /&gt;&lt;br /&gt;You may test this Web Service after installing client ActiveX on this page.&lt;br /&gt;Problems Faced&lt;br /&gt;&lt;br /&gt;    * When adding the "GrabFrame" method to Webcam Server using the ATL "Add Method to Interface", the method was created correctly in .idl and .h files but the not in the .cpp. We can find a kind of explanation on MSDN: Q198017.&lt;br /&gt;    * Before SOAP SDK SP2, SAFEARRAY(unsigned char) was not correctly handled. You need the SP2 to get a correct wrapping from SAFEARRAY(unisgned char) to base64Binary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-3731598866235249865?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/3731598866235249865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/integrate-webcam-with-net-application.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3731598866235249865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3731598866235249865'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/integrate-webcam-with-net-application.html' title='Integrate webcam with a .net application'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-5129877808639049927</id><published>2010-02-05T02:09:00.000-08:00</published><updated>2010-02-05T02:10:07.694-08:00</updated><title type='text'>Secure a .Net Application</title><content type='html'>Introduction&lt;br /&gt;&lt;br /&gt;There is no glamour in building secure ASP.NET web applications. The vast majority of developers I’ve met would much rather focus on building new &amp; flashy features that can impress their managers and end-users. Even though security can usually take a backseat during the initial stages of development, it usually comes back to bite you when it’s least expected. This article covers some of the security aspects to be aware of when developing a new web application and what to do throughout the development process to protect applications and databases against common attacks.&lt;br /&gt;Back to Reality&lt;br /&gt;&lt;br /&gt;Building web applications with ASP.NET has been getting easier as the technology and the development environment, Visual Studio, become more sophisticated. Many of the complexities are taken care of by the framework and are out of view from developers. This allows us to focus more on the business value and features of our web applications and less on technical aspects that very few really understand or appreciate. As a result, many developers believe that security is also taken care of for them and they need not to worry about it.&lt;br /&gt;&lt;br /&gt;Unfortunately the reality is quite different. Unless developers make security one of their priorities early on in the development cycle, project managers might end up with a great application but one that cannot go live without compromising the safety of their end-users and their data.&lt;br /&gt;Attacks Are Easier Than You Might Think&lt;br /&gt;&lt;br /&gt;It might be surprising to many project &amp; product managers that exploiting web applications does not necessarily require expert knowledge. Attacks are often perpetrated by hobbyists with very simple means. Here are two recent examples.&lt;br /&gt;Attack I: SQL injection at Telegraph results in 700,000 emails stolen&lt;br /&gt;&lt;br /&gt;The Attack - On March 6th, 2009, a hacker used blind SQL injection to penetrate to the web site of The Telegraph, a leading English daily paper. Based on reports, he or she was able to gain access to about 700,000 email addresses on the site’s database. Telegraph’s response can be found on their blog.&lt;br /&gt;&lt;br /&gt;Some Background – SQL statements are generally used to retrieve, update and delete data against a web application’s database. This is normally done behind the scenes and the results are displayed to a user based on their authority level. This means that the data is protected and access is granted on a selective basis.&lt;br /&gt;&lt;br /&gt;Attack Explanation - Many web applications provide some form of search capabilities where users can provide their own filtering on the data the application might display. For example, a filter to see only the records posted in 2009. If the application is not secure, a hacker can potentially exploit this functionality. Rather than supplying a value to filter upon, he might provide another SQL statement that is then injected in to the SQL statement that the application uses to retrieve data.&lt;br /&gt;&lt;br /&gt;Attack Example – Let’s assume a user only has access to the records of his department and to filter through the records, he enters some criteria. He wants to see the latest records, so he enters 2009 in the year range.&lt;br /&gt;&lt;br /&gt;The application might attempt to execute the following statement against the database: SELECT * FROM … WHERE … AND Year = 2009&lt;br /&gt;&lt;br /&gt;A hacker on the other hand, might try to trick the application and enter the following into that same year range field: 2009 OR 1=1&lt;br /&gt;&lt;br /&gt;The application, if not careful, might then execute the following statement against the database: SELECT * FROM … WHERE … AND Year = 2009 OR 1=1&lt;br /&gt;&lt;br /&gt;This would potentially provide the user with access to all the records in the system, even the ones to which they shouldn’t.&lt;br /&gt;Attack II: Authentication Security Holes at Sage&lt;br /&gt;&lt;br /&gt;The Attack – Sage, a leading provider of accounting software in the UK, was about to launch Sage Live, a small business accounting product as SaaS (software as a service). However according to ZDnet, Sage Live went dead after serious security flaws were exposed in the product. The flaws were exposed by the founder of a tiny rival. Duane Jackson, CEO of UK-based KashFlow, described what she found on her blog: “A little bit of prodding around the site and I found myself looking at… pages that only authorized people should be seeing.”&lt;br /&gt;&lt;br /&gt;Attack Explanation - Users navigate to and though web applications by going from one URL address to another, much like postal addresses point to residential homes and businesses. As a result, users can easily change the URL and its parameters that can potentially lead to pages and information that they wouldn’t ordinarily be allowed to view.&lt;br /&gt;Common ASP.NET Security Flaws&lt;br /&gt;&lt;br /&gt;There is a wide array of attacks that ASP.NET web applications need to protect against but most security holes are due to flaws in the following:&lt;br /&gt;&lt;br /&gt;- Authentication&lt;br /&gt;&lt;br /&gt;Making it easy for attackers to reveal users credentials, or worse to circumvent the application’s authentication altogether.&lt;br /&gt;&lt;br /&gt;Possible deficiencies: lack of password policy (strong passwords, expiration date etc), passing internal messages back to the browser, using dynamic SQL on the login page (SQL injection), using cookies and other insecure means to store users’ credentials, and passing user names and passwords in clear text .&lt;br /&gt;&lt;br /&gt;Possible attacks: network eavesdropping, brute force &amp; dictionary attacks, SQL injection (on login page), Cookie replay attacks and credential theft.&lt;br /&gt;&lt;br /&gt;- Authorization&lt;br /&gt;&lt;br /&gt;Allowing logged-in users to perform actions without authorization verification (i.e. vertical &amp; horizontal privilege escalation.)&lt;br /&gt;&lt;br /&gt;Possible deficiencies: inconsistent checks for user authorization for every user’s request and web page, lack of data validation and trusting data submitted by users (i.e. cookies, hidden fields, URL parameters, etc.)&lt;br /&gt;&lt;br /&gt;Possible attacks: privilege escalation attacks (horizontal and vertical), disclosure of confidential data and Data tampering attacks.&lt;br /&gt;&lt;br /&gt;- Data Validation&lt;br /&gt;&lt;br /&gt;Trusting data submitted by the user and acting upon it.&lt;br /&gt;&lt;br /&gt;Possible deficiencies: lack of consistent and strict data validation throughout the web, and failing to encode data sent to the browser.&lt;br /&gt;&lt;br /&gt;Common Attacks: cross-site scripting (XSS), SQL injection, data tampering (query string, form fields, cookies, and HTTP headers), embedded malicious characters and HTTP response splitting.&lt;br /&gt;&lt;br /&gt;- Application Configuration&lt;br /&gt;&lt;br /&gt;Using default configuration on the application and hosted server.&lt;br /&gt;&lt;br /&gt;Possible deficiencies: granting the application more permissions than it actually needs, failing to properly secure resources (operating system, database, etc.) and passing internal application information back to the browser (internal messages, exceptions and trace information.)&lt;br /&gt;&lt;br /&gt;Common Attacks: unauthorized access to administrator functionality, unauthorized access to configuration information, retrieval of clear text configuration information and unauthorized access to data stores.&lt;br /&gt;Securing Your ASP.NET Web Application&lt;br /&gt;&lt;br /&gt;Implementing security after the fact has a steep cost associated with it. Fixing software defects after the application goes into production might cost up to 15 times more than during development. Lax security also has some other indirect costs, such as damaging a company’s reputation and losing customers.&lt;br /&gt;&lt;br /&gt;While securing an ASP.NET web application can be complex, it needs to be done on a continuous basis. The .NET framework, and ASP.NET in particular, offers great features to make it easier to properly secure your web application.&lt;br /&gt;Authentication&lt;br /&gt;&lt;br /&gt;Although ASP.NET supports several authentication methods, form authentication is the most commonly used by web applications. Unfortunately, this approach is not a particularly secure approach as it sends user’s credentials to the server in clear text. Depending on requirements, you might want to consider using SSL throughout the site or at least on the login page.&lt;br /&gt;&lt;br /&gt;But since SSL might be impractical for many commercial web applications, one new &amp; unique approach that you can consider is using Silverlight. Silverlight can be embedded on any sensitive page and provide encryption of any submitted data.&lt;br /&gt;&lt;br /&gt;A web application’s authentication can be further enhanced with the following:&lt;br /&gt;&lt;br /&gt;- Password Policy&lt;br /&gt;&lt;br /&gt;Enforce a password policy including strong passwords, password expiration, and possibly locking user accounts after a few unsuccessful login attempts.&lt;br /&gt;&lt;br /&gt;- Guessing Credentials – Brute Force Attacks&lt;br /&gt;&lt;br /&gt;In addition to the above, you might want to introduce a random delay of a few seconds upon unsuccessful user login. This would make brute force attacks impractical to execute (use Thread.Sleep for this scenario.)&lt;br /&gt;&lt;br /&gt;- Password Hashing&lt;br /&gt;&lt;br /&gt;If you manage your authentication store, make sure to hash all user passwords.&lt;br /&gt;Page Authorization &amp; Data Validation&lt;br /&gt;&lt;br /&gt;Small web applications are often built as a series of fairly isolated web pages. Each page is designed to handle its own security and functionality, basically acting as a mini application. Although this approach might work when security &amp; maintenance concerns are few, it very rarely works for a larger web application.&lt;br /&gt;&lt;br /&gt;One approach that is commonly implemented, which can offer a solid data validation and authorization infrastructure, is the development of a web framework to be used by all ASP.NET web pages in a consistent manner. This web framework should be designed to employ common authorization and data validation security check points upon every user request, allowing the application to streamline and tighten many security aspects throughout the application.&lt;br /&gt;&lt;br /&gt;Building such a web framework in ASP.NET is surprisingly easy. Using .NET inheritance, we can design one or more ASP.NET base classes to inherit from the System.Web.UI.Page object. These base classes would run during each page lifecycle and would verify each user request before the results are served to the user.&lt;br /&gt;&lt;br /&gt;The following page lifecycle events are commonly used to perform security checks before the page begins processing the request: Init, InitComplete and PreLoad.&lt;br /&gt;Constructing the ASP.NET Web Framework&lt;br /&gt;&lt;br /&gt;Structuring base web pages is easy. Let’s assume that our ASP.NET web application supports three kinds of users:&lt;br /&gt;&lt;br /&gt;Unregistered users – allowed to browse anything publicly available.&lt;br /&gt;&lt;br /&gt;Logged-in users – allowed to browse anything that’s public plus their own private information.&lt;br /&gt;&lt;br /&gt;Administrators - same as a logged-in user plus some extra admin functionality.&lt;br /&gt;&lt;br /&gt;Diagram 1: Base class to serve unregistered users and the foundation for other base classes&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;public abstract class BaseWebPage : System.Web.UI.Page&lt;br /&gt;{&lt;br /&gt;      ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Note: This class should verify general information submitted by users, such as URL parameters, form data to some extent, cookies and other info that is not tied to any particular user.&lt;br /&gt;&lt;br /&gt;Diagram 2: User base class to be inherited by all pages used by logged-in users&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;public abstract class UserWebPage : BaseWebPage&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Note: This class should ensure that the user is currently logged-in and has access to the page functionality and to the date they want to view.&lt;br /&gt;&lt;br /&gt;Diagram 3: Administrator base class to be inherited by all pages used by administrators&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;public abstract class AdminWebPage : UserWebPage&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Note: This class should ensure that in the current user is indeed an administrator.&lt;br /&gt;Linking the Page to Our Web Framework&lt;br /&gt;&lt;br /&gt;Utilizing the ASP.NET web framework above requires very minor adjustments to a web page. Rather than using the default ASP.NET page base class (System.Web.UI.Page) use the appropriate base class defined earlier.&lt;br /&gt;&lt;br /&gt;For instance, if we defined a new ASPX page that is supposed to serve logged-in users we would define it as follows:&lt;br /&gt;&lt;br /&gt;Diagram 4: Sample ASPX code-behind page serving a particular user&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;public partial class ShowUserSettingsPage : UserWebPage&lt;br /&gt;{&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Performing Page Authorization &amp; Data Validation&lt;br /&gt;&lt;br /&gt;Now that we have built our web framework, all we have left is to verify user authorization per page and to perform general data validation for each request.&lt;br /&gt;&lt;br /&gt;To perform page authorization, we would define one virtual method on the BaseWebPage class to authorize the current user. Both the UserWebPage and the AdminWebPage would override this method and provide their own implementation. We would call this method on Page_Init from the BaseWebPage before any page processing is taking place.&lt;br /&gt;&lt;br /&gt;This might be implemented as follows:&lt;br /&gt;&lt;br /&gt;Diagram 5: Page authorization &amp; data validation on BaseWebPage base class&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;public abstract class BaseWebPage : System.Web.UI.Page&lt;br /&gt;    {&lt;br /&gt;        protected void Page_Init(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            AuthorizeUser();&lt;br /&gt;&lt;br /&gt;            ValidateSubmittedData();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        protected virtual void AuthorizeUser()&lt;br /&gt;        {&lt;br /&gt;            //no need to do anything for unregistered users&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        ...&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;Note: Class calls a virtual method AuthorizeUser that inheriting classes can implement to force specific user access rights, and once the user is authorized, the class verifies all data submitted to the web page.&lt;br /&gt;&lt;br /&gt;Diagram 6: Page authorization on UserWebPage for ASP.NET web pages designated for logged-in users&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;public abstract class UserWebPage : BaseWebPage&lt;br /&gt;    {&lt;br /&gt;        protected override void AuthorizeUser()&lt;br /&gt;        {&lt;br /&gt;            if(!User.IsInRole("User"))&lt;br /&gt;            {&lt;br /&gt;                //user cannot see the page  - redirect to appropriate page&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;Note: Class overrides the AuthorizeUser to make sure current user is logged-in.&lt;br /&gt;More on Data Validation&lt;br /&gt;&lt;br /&gt;A centralized web framework can offer many security benefits to web applications, but it often needs to be complemented with page-specific security measures to ensure proper data validation.&lt;br /&gt;&lt;br /&gt;Web pages should employ data validation based on the following guidelines:&lt;br /&gt;&lt;br /&gt;    * Data validation – web pages should enforce strict data validation on any piece of data not strictly covered by the web framework. This might include additional type casting (for instance ensures that a piece of data is an integer) range and length. Regular expressions and Regex class are a great a great way to constrain input in ASP.NET.&lt;br /&gt;    * Encoding – any web page displaying data on the browser that cannot be guaranteed to be safe should be encoded using Server.HtmlEncode to prevent any malicious cross-site scripting (XSS) attacks.&lt;br /&gt;    * URL write actions– avoid performing database write actions against URL parameters even if data is valid and the user has authorization to perform such actions. Also ensure that every POST action is actually done from an internal application page to prevent cross-site request forgeries (CSRF) attacks.&lt;br /&gt;    * Exceptions – make sure to catch any possible exceptions and only send user-friendly messages to the browser to avoid revealing any sensitive information that might reveal an application’s vulnerabilities.&lt;br /&gt;&lt;br /&gt;Data Authorization – Data Access Framework&lt;br /&gt;&lt;br /&gt;N-tier infrastructure is not a foreign concept to most ASP.NET developers and can provide substantial benefits in terms of performance and scalability. Among the many benefits of n-tier architecture, it also can be used to centralize and enforce strict authorization rules.&lt;br /&gt;&lt;br /&gt;To do this effectively, a data access framework should be built as an isolated component and should be designed to do the following for each piece of functionality exposed to the ASP.NET web application:&lt;br /&gt;&lt;br /&gt;    * Parameter Validation - validate all parameters supplied by the user for type, range, length, etc.&lt;br /&gt;    * Authentication - ensure that the calling user is a valid user.&lt;br /&gt;    * Authorization – verify that the user has rights to perform the current database operation.&lt;br /&gt;    * Database Queries - avoid using dynamic SQL queries, if possible, and only use parameters.&lt;br /&gt;    * User Data - only send back data that the current user is entitled to view or return user-friendly exceptions.&lt;br /&gt;&lt;br /&gt;Application Configuration&lt;br /&gt;&lt;br /&gt;Different applications require different configurations but the focus of this section is on those that fall under the responsibility of the web developer.&lt;br /&gt;Encrypting Sensitive Configuration Information&lt;br /&gt;&lt;br /&gt;Any sensitive configuration information on the web.config and beyond should be properly encrypted to avoid exposing sensitive details like connection strings to potential attackers. You can use the web.config protectedData section to indicate which sections of the web.config file should be encrypted.&lt;br /&gt;&lt;br /&gt;The following shows how to protect the connectionStrings section:&lt;br /&gt;&lt;br /&gt;Diagram 7: Protecting the connectionStrings section within the web.config&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;&lt;protectedData&gt;&lt;br /&gt;  &lt;protecteddatasections&gt;&lt;br /&gt;    &lt;add name="connectionStrings" provider="RSAProtectedConfigurationProvider"&gt;&lt;br /&gt;  &lt;/add&gt;&lt;br /&gt;&lt;/protecteddatasections&gt;&lt;br /&gt;&lt;br /&gt;Note: This is a more suitable way to protect data across different web servers. Unlike DPAPI, the information is not tied down to any particular machine.&lt;br /&gt;&lt;br /&gt;You can now use aspnet_regiis to encrypt the appropriate section:&lt;br /&gt;aspnet_regiis -pef connectionStrings "c:\...\MyWebApplication"&lt;br /&gt;Protect Internal Exceptions&lt;br /&gt;&lt;br /&gt;Prevent detailed exceptions from being displayed on the client’s browser entirely or display this only when the client is browsing on the web server itself.&lt;br /&gt;Final Note&lt;br /&gt;&lt;br /&gt;Even though it can be tempting to push off dealing with security (or avoiding it altogether), its importance should never be underestimated. An attack or even a request for a security audit by a customer can cost you time, money and potentially your company’s reputation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-5129877808639049927?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/5129877808639049927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/secure-net-application.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5129877808639049927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/5129877808639049927'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/secure-net-application.html' title='Secure a .Net Application'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-4220722150326512881</id><published>2010-02-05T01:51:00.000-08:00</published><updated>2010-02-05T02:02:26.856-08:00</updated><title type='text'>COM+ and the .NET Framework Building a complete COM+ Server component using C# and .NET</title><content type='html'>To ease development, I recommend using the Visual Studio.NET IDE. However, you are free to develop your application in the favorite editor of your choice, using the command-line to execute the various commands to build and deploy it.&lt;br /&gt;&lt;br /&gt;Building COM+ aware components using the .NET Framework&lt;br /&gt;&lt;br /&gt;To develop .NET managed components that can be configured to function under the COM+ Runtime, you need to provide these components with numerous attributes defined in the System.EnterpriseServices namespace. To start off, each .NET class that's supposed to run under COM+ needs to derive from the System.ServicedComponent class. This base class provides default implementations of the classic MTS/COM+ interface IObjectControl - Activate(), Deactivate(), and CanBePooled(). You can override the default implementations if you wish to do so, just as will be seen shortly.&lt;br /&gt;&lt;br /&gt;Once any number of COM+ centric attributes are added to the .NET component, the assembly will have to be compiled. However, to place this assembly under the control of COM+, a new utility (regsvcs.exe) will have to be used as we will see soon. In addition to installing the component into the COM+ catalog, this utility also provides a lot of other services that we shall soon see.&lt;br /&gt;&lt;br /&gt;Finally, for the COM+ Surrogate (dllhost.exe) to locate your assembly and to host it in a given activity, it must be able to locate your binary. Therefore, you should install your assembly into the system's Global Assembly Cache (GAC).&lt;br /&gt;&lt;br /&gt;The various steps that are involved in creating a COM+ Server Component using C# and the .NET Framework are as follows (I'm going to assume you're using the VS.NET IDE):&lt;br /&gt;&lt;br /&gt;   1.&lt;br /&gt;&lt;br /&gt;      Create a Visual C# - Class Library project&lt;br /&gt;   2.&lt;br /&gt;&lt;br /&gt;      Generate a Key-Value pair to use when deploying your Shared Assembly&lt;br /&gt;   3.&lt;br /&gt;&lt;br /&gt;      Configure your Project Property Pages with the right information&lt;br /&gt;   4.&lt;br /&gt;&lt;br /&gt;      Develop the AccountManager.cs library&lt;br /&gt;   5.&lt;br /&gt;&lt;br /&gt;      Modify the generated AssemblyInfo.cs to add the right assembly information&lt;br /&gt;   6.&lt;br /&gt;&lt;br /&gt;      Build the Project Files&lt;br /&gt;   7.&lt;br /&gt;&lt;br /&gt;      Deploy the component as a Shared Assembly, and Configure the Assembly in the COM+ Catalog&lt;br /&gt;&lt;br /&gt;The BookKeeper Module&lt;br /&gt;&lt;br /&gt;My goal is to simplify illustration of a typical COM+ serviced component development process. I am therefore, in this article, going to reuse the BookKeeper example for all database operations. As a result, all our data is going to be maintained in an XML datastore!!! I had used the BookKeeper example in an earlier article to illustrate ADO.NET's disconnected operation facility - the DataSet. To refresh, the DataSet facilitates the client to manipulate and update a local copy of any number of related tables while still disconnected from the data source and submit the modified data back for processing using a related data adapter at a later point in time.&lt;br /&gt;&lt;br /&gt;The AccountManager Module&lt;br /&gt;&lt;br /&gt;Our hypothetical AccountManager Module (that we will build in this article), is actually a COM+ Server component that performs just a couple of functions. It is the module that manages creation and deletion of accounts (Checking accounts or Savings accounts) for a Large Commercial Bank Project. It offers no other services except "Create Account", and "Delete Account".&lt;br /&gt;&lt;br /&gt;1. Create a Visual C# - Class Library project&lt;br /&gt;&lt;br /&gt;Create a new Visual C# Class Library project. Remember that the COM+ Runtime can only host types contained in a DLL.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;2. Generate a Key-Value pair to use when deploying your Shared Assembly&lt;br /&gt;&lt;br /&gt;Shared Assemblies are those that can be used by any client application, such as a system DLL that every process in the system can use. Unlike private-assemblies, shared assemblies must be published or registered in the system's Global Assembly Cache (GAC). As soon as they are registered in the GAC, they act as system components. An essential requirement for GAC registration is that the component must possess originator and version information. In addition to other metadata information, these two items allow multiple versions of the same component to be registered and executed on the same machine. Unlike Classic COM, we don't have to store any information in the system registry for clients to use these shared assemblies.&lt;br /&gt;&lt;br /&gt;There are three general steps to registering shared assemblies in the GAC:&lt;br /&gt;&lt;br /&gt;   1.&lt;br /&gt;&lt;br /&gt;      The Shared Name (sb.exe) utility should be used to obtain the public/private key pair. This utility generates a random key pair value, and stores it in an output file - for example, AccountManager.key.&lt;br /&gt;   2.&lt;br /&gt;&lt;br /&gt;      Build the assembly with an assembly version number and the key information in the AccountManager.key&lt;br /&gt;   3.&lt;br /&gt;&lt;br /&gt;      Using the .NET Global Assembly Cache (gacutil.exe) utility, register the assembly in the GAC.&lt;br /&gt;&lt;br /&gt;The assembly now becomes a shared assembly and can be used by any client in the system.&lt;br /&gt;&lt;br /&gt;Therefore, as a first step, use the Shared Name Utility to obtain a public/private key pair and store it in a file (AccountManager.key, in this case) as shown below.&lt;br /&gt;Command Prompt&lt;br /&gt;C:\MyProjects\Cornucopia\COMplus\BankServer\AccountManager&gt;sn -k AccountManager.key&lt;br /&gt;&lt;br /&gt;Microsoft (R) .NET Framework Strong Name Utility Version 1.0.2914.16&lt;br /&gt;Copyright (C) Microsoft Corp. 1998-2001. All rights reserved.&lt;br /&gt;&lt;br /&gt;Key pair written to AccountManager.key&lt;br /&gt;&lt;br /&gt;C:\MyProjects\Cornucopia\COMplus\BankServer\AccountManager&gt;&lt;br /&gt;&lt;br /&gt;The -k option generates the random key pair and saves the key information in the AccountManager.key file. We use this file as input when we build our Shared Assemblies.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;3.  Configure your Project Property Pages with the right information&lt;br /&gt;&lt;br /&gt;Configure the Project Properties with the right information. Make sure you specify the Assembly Name that you want for the Assembly. Specifically, move to the General tab, and in the Wrapper Assembly Key File area, enter the key file to use. In this case, it is AccountManager.key.&lt;br /&gt;&lt;br /&gt;Move to the Reference Path Properties area, and select the directory that contains the BookKeeper executable.&lt;br /&gt;&lt;br /&gt;Go to "Project Dependancy" and select the BookKeeper as a dependancy for this project. This means the BookKeeper project has to be compiled before compiling this project.&lt;br /&gt;&lt;br /&gt;To the AccountManager project files, also add the BookKeeper.cs, and the AccountKey.cs files from the BookKeeper project.&lt;br /&gt;&lt;br /&gt;4. Develop the AccountManager.cs library&lt;br /&gt;&lt;br /&gt;Transactions&lt;br /&gt;&lt;br /&gt;To develop a .NET class that supports transactions, here's what you have to do:&lt;br /&gt;&lt;br /&gt;    * The class must derive from the System.ServicedComponent class to exploit COM+ Services as shown in Line 94.&lt;br /&gt;    * The class must be created with the correct Transaction attribute such as Transaction (TransactionOption.Required) as shown in Line 78.&lt;br /&gt;&lt;br /&gt;Besides this, you can use the System.EnterpriseServices.ContextUtil class to obtain information about the COM+ object context as shown in Line 138. This class exposes important methods of COM+ like SetComplete() and SetAbort(), and IsCallerInRole(), and important COM+ properties like IsInTransaction, and MyTransactionVote. Additionally, while it's not necessary to specify COM+ Application installation options, you can always specify what you want. Notice that we use attributes to specify a number of things.&lt;br /&gt;&lt;br /&gt;In the AccountManager.create() method, we simply call ContextUtil.SetComplete() - Line 138 -when we've successfully created a new account into our database. If something has gone wrong during the process, we will vote to abort the transaction by calling ContextUtil.SetAbort() as shown on Line 142.&lt;br /&gt;&lt;br /&gt;Instead of calling ContextUtil.SetComplete() and ContextUtil.SetAbort() explicitly, we can also use the AutoComplete( true ) attribute, as shown on line 165 which is conceptually equivalent to the previously shown AccountManager.create() method.&lt;br /&gt;AccountManager.cs&lt;br /&gt;1:&lt;br /&gt;2:&lt;br /&gt;3:&lt;br /&gt;4:&lt;br /&gt;5:&lt;br /&gt;6:&lt;br /&gt;7:&lt;br /&gt;8:&lt;br /&gt;9:&lt;br /&gt;10:&lt;br /&gt;11:&lt;br /&gt;12:&lt;br /&gt;13:&lt;br /&gt;14:&lt;br /&gt;15:&lt;br /&gt;16:&lt;br /&gt;17:&lt;br /&gt;18:&lt;br /&gt;19:&lt;br /&gt;20:&lt;br /&gt;21:&lt;br /&gt;22:&lt;br /&gt;23:&lt;br /&gt;24:&lt;br /&gt;25:&lt;br /&gt;26:&lt;br /&gt;27:&lt;br /&gt;28:&lt;br /&gt;29:&lt;br /&gt;30:&lt;br /&gt;31:&lt;br /&gt;32:&lt;br /&gt;33:&lt;br /&gt;34:&lt;br /&gt;35:&lt;br /&gt;36:&lt;br /&gt;37:&lt;br /&gt;38:&lt;br /&gt;39:&lt;br /&gt;40:&lt;br /&gt;41:&lt;br /&gt;42:&lt;br /&gt;43:&lt;br /&gt;44:&lt;br /&gt;45:&lt;br /&gt;46:&lt;br /&gt;47:&lt;br /&gt;48:&lt;br /&gt;49:&lt;br /&gt;50:&lt;br /&gt;51:&lt;br /&gt;52:&lt;br /&gt;53:&lt;br /&gt;54:&lt;br /&gt;55:&lt;br /&gt;56:&lt;br /&gt;57:&lt;br /&gt;58:&lt;br /&gt;59:&lt;br /&gt;60:&lt;br /&gt;61:&lt;br /&gt;62:&lt;br /&gt;63:&lt;br /&gt;64:&lt;br /&gt;65:&lt;br /&gt;66:&lt;br /&gt;67:&lt;br /&gt;68:&lt;br /&gt;69:&lt;br /&gt;70:&lt;br /&gt;71:&lt;br /&gt;72:&lt;br /&gt;73:&lt;br /&gt;74:&lt;br /&gt;75:&lt;br /&gt;76:&lt;br /&gt;77:&lt;br /&gt;78:&lt;br /&gt;79:&lt;br /&gt;80:&lt;br /&gt;81:&lt;br /&gt;82:&lt;br /&gt;83:&lt;br /&gt;84:&lt;br /&gt;85:&lt;br /&gt;86:&lt;br /&gt;87:&lt;br /&gt;88:&lt;br /&gt;89:&lt;br /&gt;90:&lt;br /&gt;91:&lt;br /&gt;92:&lt;br /&gt;93:&lt;br /&gt;94:&lt;br /&gt;95:&lt;br /&gt;96:&lt;br /&gt;97:&lt;br /&gt;98:&lt;br /&gt;99:&lt;br /&gt;100:&lt;br /&gt;101:&lt;br /&gt;102:&lt;br /&gt;103:&lt;br /&gt;104:&lt;br /&gt;105:&lt;br /&gt;106:&lt;br /&gt;107:&lt;br /&gt;108:&lt;br /&gt;109:&lt;br /&gt;110:&lt;br /&gt;111:&lt;br /&gt;112:&lt;br /&gt;113:&lt;br /&gt;114:&lt;br /&gt;115:&lt;br /&gt;116:&lt;br /&gt;117:&lt;br /&gt;118:&lt;br /&gt;119:&lt;br /&gt;120:&lt;br /&gt;121:&lt;br /&gt;122:&lt;br /&gt;123:&lt;br /&gt;124:&lt;br /&gt;125:&lt;br /&gt;126:&lt;br /&gt;127:&lt;br /&gt;128:&lt;br /&gt;129:&lt;br /&gt;130:&lt;br /&gt;131:&lt;br /&gt;132:&lt;br /&gt;133:&lt;br /&gt;134:&lt;br /&gt;135:&lt;br /&gt;136:&lt;br /&gt;137:&lt;br /&gt;138:&lt;br /&gt;139:&lt;br /&gt;140:&lt;br /&gt;141:&lt;br /&gt;142:&lt;br /&gt;143:&lt;br /&gt;144:&lt;br /&gt;145:&lt;br /&gt;146:&lt;br /&gt;147:&lt;br /&gt;148:&lt;br /&gt;149:&lt;br /&gt;150:&lt;br /&gt;151:&lt;br /&gt;152:&lt;br /&gt;153:&lt;br /&gt;154:&lt;br /&gt;155:&lt;br /&gt;156:&lt;br /&gt;157:&lt;br /&gt;158:&lt;br /&gt;159:&lt;br /&gt;160:&lt;br /&gt;161:&lt;br /&gt;162:&lt;br /&gt;163:&lt;br /&gt;164:&lt;br /&gt;165:&lt;br /&gt;166:&lt;br /&gt;167:&lt;br /&gt;168:&lt;br /&gt;169:&lt;br /&gt;170:&lt;br /&gt;171:&lt;br /&gt;172:&lt;br /&gt;173:&lt;br /&gt;174:&lt;br /&gt;175:&lt;br /&gt;176:&lt;br /&gt;177:&lt;br /&gt;178:&lt;br /&gt;179:&lt;br /&gt;180:&lt;br /&gt;181:&lt;br /&gt;182:&lt;br /&gt;183:&lt;br /&gt;184:&lt;br /&gt;185:&lt;br /&gt;186:&lt;br /&gt;187:&lt;br /&gt;188:&lt;br /&gt;189:&lt;br /&gt;190:&lt;br /&gt;191:&lt;br /&gt;192:&lt;br /&gt;193:&lt;br /&gt;194:&lt;br /&gt;195:&lt;br /&gt;196:&lt;br /&gt;197:&lt;br /&gt;198:&lt;br /&gt;199:&lt;br /&gt;200:&lt;br /&gt;201:&lt;br /&gt;202:&lt;br /&gt;203:&lt;br /&gt;204:&lt;br /&gt;205:&lt;br /&gt;206:&lt;br /&gt;207:&lt;br /&gt;208:&lt;br /&gt;209:&lt;br /&gt;210:&lt;br /&gt;211:&lt;br /&gt;212:&lt;br /&gt;213:&lt;br /&gt;214:&lt;br /&gt;215:&lt;br /&gt;216:&lt;br /&gt;217:&lt;br /&gt;218:&lt;br /&gt;219:&lt;br /&gt;220:&lt;br /&gt;221:&lt;br /&gt;222:&lt;br /&gt;223:&lt;br /&gt;224:&lt;br /&gt;225:&lt;br /&gt;226:&lt;br /&gt;227:&lt;br /&gt;228:&lt;br /&gt;229:&lt;br /&gt;230:&lt;br /&gt;231:&lt;br /&gt;232:&lt;br /&gt;233:&lt;br /&gt;234:&lt;br /&gt;235:&lt;br /&gt;236:&lt;br /&gt;237:&lt;br /&gt;238:&lt;br /&gt;239:&lt;br /&gt;240:&lt;br /&gt;241: &lt;br /&gt;242:&lt;br /&gt; //////////////////////////////////////////////////////&lt;br /&gt;/// The following example illustrates a COM+ type&lt;br /&gt;/// developed using C# and the .NET Framework.&lt;br /&gt;///&lt;br /&gt;/// author: Gopalan Suresh Raj&lt;br /&gt;/// Copyright (c), 2001. All Rights Reserved.&lt;br /&gt;/// URL: http://gsraj.tripod.com/&lt;br /&gt;/// email: gopalan@gmx.net&lt;br /&gt;///&lt;br /&gt;/// &lt;register&gt;&lt;br /&gt;/// gacutil /i Bank.dll&lt;br /&gt;/// regsvcs /fc Bank.dll&lt;br /&gt;/// &lt;/register&gt;&lt;br /&gt;//////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.EnterpriseServices;&lt;br /&gt;// Include the following for the Trace class&lt;br /&gt;using System.Diagnostics;  &lt;br /&gt;// Include the following for Windows Message Box&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;// Include the BookKeeper namespace&lt;br /&gt;using BookKeeper;&lt;br /&gt;&lt;br /&gt;namespace Bank {&lt;br /&gt;&lt;br /&gt;  ///////////////////////////////////////////////////////////////&lt;br /&gt;  /// &lt;summary&gt;&lt;br /&gt;  /// The Account Manager interface&lt;br /&gt;  /// &lt;/summary&gt;&lt;br /&gt;  /// &lt;remarks&gt;&lt;br /&gt;  /// This interface defines create and delete methods to&lt;br /&gt;  /// add or delete Bank Accounts&lt;br /&gt;  /// &lt;/remarks&gt;&lt;br /&gt;  ///////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;  /// Indicate whether a managed interface is dual, IDispatch or&lt;br /&gt;  /// IUnknown based when exposed to COM&lt;br /&gt;  [ InterfaceTypeAttribute( ComInterfaceType.InterfaceIsDual ) ]&lt;br /&gt;&lt;br /&gt;  public interface IAccountManager {&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// The create method&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    /// &lt;remarks&gt;&lt;br /&gt;    /// Method used to create a new Bank account&lt;br /&gt;    /// &lt;/remarks&gt;&lt;br /&gt;    /// &lt;param name="type"&gt;Either Checking or Savings&lt;/param&gt;&lt;br /&gt;    /// &lt;param name="customerNames"&gt;Customers who own this account&lt;/param&gt;&lt;br /&gt;    /// &lt;param name="startingBalance"&gt;Initial Deposit&lt;/param&gt;&lt;br /&gt;    /// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;    int create (AccountType type, string[] customerNames, float startingBalance);&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// The delete method&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    /// &lt;remarks&gt;&lt;br /&gt;    /// Method used to delete and existing Bank account&lt;br /&gt;    /// &lt;/remarks&gt;&lt;br /&gt;    /// &lt;param name="accountKey"&gt;the Account Number&lt;/param&gt;&lt;br /&gt;    /// &lt;returns&gt;true if Account deleted, false if not&lt;/returns&gt;&lt;br /&gt;    bool delete (int accountKey);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  ///////////////////////////////////////////////////////////////&lt;br /&gt;  /// &lt;summary&gt;&lt;br /&gt;  /// AccountManager used to create new Accounts or delete accounts.&lt;br /&gt;  /// &lt;/summary&gt;&lt;br /&gt;  ///////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;  /// Specify a name for your serviced component&lt;br /&gt;  [ ProgId( "COM+ Bank Server Account Manager" ) ]&lt;br /&gt;  /// Add content to hosting COM+ App's description field&lt;br /&gt;  [ Description( "COM+ Bank Server Account Manager" ) ]&lt;br /&gt;  /// Configure component's Transaction Option&lt;br /&gt;  [ Transaction( TransactionOption.Required ) ]&lt;br /&gt;  /// Configure component's object pooling&lt;br /&gt;  [ ObjectPooling( MinPoolSize = 5, MaxPoolSize = 10, CreationTimeout = 20 ) ]&lt;br /&gt;  /// Specify COM+ Context Attributes&lt;br /&gt;  [ MustRunInClientContext( false ) ]&lt;br /&gt;  /// Enable event tracking&lt;br /&gt;  [ EventTrackingEnabled( true ) ]&lt;br /&gt;  /// Enable JITA for the component&lt;br /&gt;  [ JustInTimeActivation( true ) ]&lt;br /&gt;  /// Enable Construction String Support for the component&lt;br /&gt;  [ ConstructionEnabled( Enabled=true, Default="Gopalan's Bank Server" ) ]&lt;br /&gt;  /// Configure activity-based Synchronization for the component&lt;br /&gt;  [ Synchronization( SynchronizationOption.Required ) ]&lt;br /&gt;  /// Indicate the type of class interface that will be generated for this class&lt;br /&gt;  [ ClassInterface( ClassInterfaceType.AutoDual ) ]&lt;br /&gt;&lt;br /&gt;  public class AccountManager : ServicedComponent, IAccountManager {&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// Public No-argument Default Constructor&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    public AccountManager() {&lt;br /&gt;      MessageBox.Show ("Bank::AccountManager() invoked...");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /////////////////////////////////////////////////////////////////////////&lt;br /&gt;    /// The Following methods support core functionality required of the&lt;br /&gt;    /// AccountManager component and implement the IAccountManager interface&lt;br /&gt;    /////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// The create method&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    /// &lt;remarks&gt;&lt;br /&gt;    /// Method used to create a new Bank account&lt;br /&gt;    /// &lt;/remarks&gt;&lt;br /&gt;    /// &lt;param name="type"&gt;Either Checking or Savings&lt;/param&gt;&lt;br /&gt;    /// &lt;param name="customerNames"&gt;Customers who own this account&lt;/param&gt;&lt;br /&gt;    /// &lt;param name="startingBalance"&gt;Initial Deposit&lt;/param&gt;&lt;br /&gt;    /// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;&lt;br /&gt;    /// Add content to hosting COM+ App's description field&lt;br /&gt;    [ Description( "Creates a new account for the Bank Server" ) ]&lt;br /&gt;&lt;br /&gt;    public int create (AccountType type, string[] customerNames, float startingBalance) {&lt;br /&gt;      MessageBox.Show ("Bank::create() invoked...");&lt;br /&gt;      AccountKey key = null;&lt;br /&gt;      try {&lt;br /&gt;        // Create the BookKeeper class&lt;br /&gt;        BookKeeper.BookKeeper keeper = new BookKeeper.BookKeeper();&lt;br /&gt;        if (null != keeper) {&lt;br /&gt;          // Call the BookKeeper to create a new Bank Account&lt;br /&gt;          key = keeper.createAccount (type, customerNames, startingBalance);&lt;br /&gt;          // Clean-up the BookKeeper object&lt;br /&gt;          keeper.Dispose();&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;          throw new Exception ( "BookKeeper Object could not be created." );&lt;br /&gt;        }&lt;br /&gt;        // Since everything went well, commit the changes&lt;br /&gt;        ContextUtil.SetComplete();&lt;br /&gt;      }&lt;br /&gt;      catch (Exception exception) {&lt;br /&gt;        // An Error occured, so rollback the changes&lt;br /&gt;        ContextUtil.SetAbort();&lt;br /&gt;&lt;br /&gt;        // Trace the current COM+ context ID (its GUID) to the output window&lt;br /&gt;        // use the ContextId static property of ContextUtil&lt;br /&gt;        Guid contextID = ContextUtil.ContextId;&lt;br /&gt;        String traceMessage = "Context ID is " + contextID.ToString();&lt;br /&gt;        Trace.WriteLine (traceMessage.ToString ());&lt;br /&gt;&lt;br /&gt;        MessageBox.Show (exception.ToString (), "Bank::create()");&lt;br /&gt;      }&lt;br /&gt;      return key.Key;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// The delete method&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    /// &lt;remarks&gt;&lt;br /&gt;    /// Method used to delete and existing Bank account&lt;br /&gt;    /// &lt;/remarks&gt;&lt;br /&gt;    /// &lt;param name="accountKey"&gt;the Account Number&lt;/param&gt;&lt;br /&gt;    /// &lt;returns&gt;true if Account deleted, false if not&lt;/returns&gt;&lt;br /&gt;&lt;br /&gt;    /// Take advantage of COM+'s method auto-deactivation&lt;br /&gt;    [ AutoComplete( true ) ]&lt;br /&gt;      /// Add content to hosting COM+ App's description field&lt;br /&gt;    [ Description( "Deletes an existing account from the Bank Server" ) ]&lt;br /&gt;&lt;br /&gt;    public bool delete (int accountKey) {&lt;br /&gt;      bool result = false;&lt;br /&gt;      MessageBox.Show ("Bank::delete() invoked...", "Key Value = "+accountKey);&lt;br /&gt;      /*&lt;br /&gt;      try {&lt;br /&gt;        // Programming Role based security&lt;br /&gt;        SecurityCallContext callContext;&lt;br /&gt;        callContext = SecurityCallContext.CurrentCall;&lt;br /&gt;        string caller = callContext.DirectCaller.AccountName;&lt;br /&gt;        bool isInRole = callContext.IsCallerInRole ( "Manager" );&lt;br /&gt;        if (false == isInRole) {&lt;br /&gt;          throw new Exception ( "Only Managers can delete Customers" );&lt;br /&gt;        }&lt;br /&gt;        */&lt;br /&gt;        BookKeeper.BookKeeper keeper = new BookKeeper.BookKeeper();&lt;br /&gt;        if (null != keeper) {&lt;br /&gt;          AccountKey key = new AccountKey();&lt;br /&gt;          key.Key = accountKey;&lt;br /&gt;          result = keeper.deleteAccount (key);&lt;br /&gt;          keeper.Dispose();&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;          throw new Exception ( "BookKeeper Object could not be created." );&lt;br /&gt;        }&lt;br /&gt;      /*}&lt;br /&gt;      catch (Exception exception) {&lt;br /&gt;        Guid contextID = ContextUtil.ContextId;&lt;br /&gt;        String traceMessage = "Context ID is " + contextID.ToString();&lt;br /&gt;        Trace.WriteLine (traceMessage.ToString ());&lt;br /&gt;&lt;br /&gt;        MessageBox.Show (exception.ToString (), "Bank::delete()");&lt;br /&gt;      }*/&lt;br /&gt;      return result;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /////////////////////////////////////////////////////////////////////////&lt;br /&gt;    /// All the Following methods support overriding functionality required for&lt;br /&gt;    /// implementing some of the COM+ support interfaces like IObjectConstruct.&lt;br /&gt;    /////////////////////////////////////////////////////////////////////////&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// The method is called after the component's constructor&lt;br /&gt;    /// and is passed in the user specific constructionString&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    /// &lt;param name="constructionString"&gt;&lt;/param&gt;&lt;br /&gt;    override public void Construct (string constructionString) {&lt;br /&gt;      MessageBox.Show ("Bank::Construct() invoked...");&lt;br /&gt;      MessageBox.Show (constructionString, "Construction String");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// Do context specific initialization in this method&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    override public void Activate () {&lt;br /&gt;      MessageBox.Show ("Bank::Activate() invoked...");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// Do context specific cleanup in this method&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    override public void Deactivate () {&lt;br /&gt;      MessageBox.Show ("Bank::Deactivate() invoked...");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// Object Pooling support method&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    /// &lt;returns&gt;true if pooling is supported, false if not&lt;/returns&gt;&lt;br /&gt;    override public bool CanBePooled () {&lt;br /&gt;      MessageBox.Show ("Bank::CanBePooled() invoked...");&lt;br /&gt;      return true;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Object Pooling&lt;br /&gt;&lt;br /&gt;Object Pooling is a feature that was introduced in COM+, but was missing in MTS. Object Pooling allows you to minimize the use of system resources, by pooling objects that support transactions but are expensive to create. This improves performance and helps system scalability. If you want to support object pooling in you components, you need to derive from the System.ServicedComponent class, and override any of the Activate(), Deactivate(), and CanBePooled() methods, and specify object pooling requirements in an ObjectPooling attribute as shown on Line 80. You can take advantage of the Activate() and Deactivate() methods to perform the appropriate initialization and cleanup. The CanBePooled() method is used to tell COM+ whether this object can be pooled or not. This way, you can provide any expensive object-creation functionality in the constructor of the component.&lt;br /&gt;&lt;br /&gt;Since our COM+ components support Object Pooling, The COM+ runtime activates and deactivates them as required. After each Client call has been serviced, it puts the component object back into the object pool. As soon as a new Client call arrives, it picks the same component object back from the pool to service the new request.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;5. Modify the generated AssemblyInfo.cs to add the right assembly information&lt;br /&gt;&lt;br /&gt;You provide the compiler with your assembly information in an assembly file called AssemblyInfo.cs. The assembly information file is compiled with the  rest of the project's source files. The information is in the form of assembly attributes - directives to the compiler on the information to embed in the assembly.&lt;br /&gt;AssemblyInfo.cs&lt;br /&gt;1:&lt;br /&gt;2:&lt;br /&gt;3:&lt;br /&gt;4:&lt;br /&gt;5:&lt;br /&gt;6:&lt;br /&gt;7:&lt;br /&gt;8:&lt;br /&gt;9:&lt;br /&gt;10:&lt;br /&gt;11:&lt;br /&gt;12:&lt;br /&gt;13:&lt;br /&gt;14:&lt;br /&gt;15:&lt;br /&gt;16:&lt;br /&gt;17:&lt;br /&gt;18:&lt;br /&gt;19:&lt;br /&gt;20:&lt;br /&gt;21:&lt;br /&gt;22:&lt;br /&gt;23:&lt;br /&gt;24:&lt;br /&gt;25:&lt;br /&gt;26:&lt;br /&gt;27:&lt;br /&gt;28:&lt;br /&gt;29:&lt;br /&gt;30:&lt;br /&gt;31:&lt;br /&gt;32:&lt;br /&gt;33:&lt;br /&gt;34:&lt;br /&gt;35:&lt;br /&gt;36:&lt;br /&gt;37:&lt;br /&gt;38:&lt;br /&gt;39:&lt;br /&gt;40:&lt;br /&gt;41:&lt;br /&gt;42:&lt;br /&gt;43:&lt;br /&gt;44:&lt;br /&gt;45:&lt;br /&gt;46:&lt;br /&gt;47:&lt;br /&gt;48:&lt;br /&gt;49:&lt;br /&gt;50:&lt;br /&gt;51:&lt;br /&gt;52:&lt;br /&gt;53:&lt;br /&gt;54:&lt;br /&gt;55:&lt;br /&gt;56:&lt;br /&gt;57:&lt;br /&gt;58:&lt;br /&gt;59:&lt;br /&gt;60:&lt;br /&gt;61:&lt;br /&gt;62:&lt;br /&gt; using System.Reflection;&lt;br /&gt;using System.Runtime.CompilerServices;&lt;br /&gt;using System.EnterpriseServices;&lt;br /&gt;&lt;br /&gt;//&lt;br /&gt;// General Information about an assembly is controlled through the following&lt;br /&gt;// set of attributes. Change these attribute values to modify the information&lt;br /&gt;// associated with an assembly.&lt;br /&gt;//&lt;br /&gt;[assembly: AssemblyTitle("AccountManager for Bank")]&lt;br /&gt;[assembly: AssemblyDescription("Creates and Deletes Accounts for the Bank")]&lt;br /&gt;[assembly: AssemblyConfiguration("")]&lt;br /&gt;[assembly: AssemblyCompany("eCommWare Corporation")]&lt;br /&gt;[assembly: AssemblyProduct("COM+ Bank Server")]&lt;br /&gt;[assembly: AssemblyCopyright("(c) 2001, Gopalan Suresh Raj. All Rights Reserved.")]&lt;br /&gt;[assembly: AssemblyTrademark("Web Cornucopia")]&lt;br /&gt;[assembly: AssemblyCulture("en-US")]&lt;br /&gt;&lt;br /&gt;//&lt;br /&gt;// Version information for an assembly consists of the following four values:&lt;br /&gt;//&lt;br /&gt;//      Major Version&lt;br /&gt;//      Minor Version&lt;br /&gt;//      Build Number&lt;br /&gt;//      Revision&lt;br /&gt;//&lt;br /&gt;// You can specify all the values or you can default the Revision and Build Numbers&lt;br /&gt;// by using the '*' as shown below:&lt;br /&gt;&lt;br /&gt;[assembly: AssemblyVersion("1.0.0.0")]&lt;br /&gt;&lt;br /&gt;//&lt;br /&gt;// In order to sign your assembly you must specify a key to use. Refer to the&lt;br /&gt;// Microsoft .NET Framework documentation for more information on assembly signing.&lt;br /&gt;//&lt;br /&gt;// Use the attributes below to control which key is used for signing.&lt;br /&gt;//&lt;br /&gt;// Notes:&lt;br /&gt;//   (*) If no key is specified, the assembly is not signed.&lt;br /&gt;//   (*) KeyName refers to a key that has been installed in the Crypto Service&lt;br /&gt;//       Provider (CSP) on your machine. KeyFile refers to a file which contains&lt;br /&gt;//       a key.&lt;br /&gt;//   (*) If the KeyFile and the KeyName values are both specified, the&lt;br /&gt;//       following processing occurs:&lt;br /&gt;//       (1) If the KeyName can be found in the CSP, that key is used.&lt;br /&gt;//       (2) If the KeyName does not exist and the KeyFile does exist, the key&lt;br /&gt;//           in the KeyFile is installed into the CSP and used.&lt;br /&gt;//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.&lt;br /&gt;//       When specifying the KeyFile, the location of the KeyFile should be&lt;br /&gt;//       relative to the project output directory which is&lt;br /&gt;//       %Project Directory%\obj\&lt;configuration&gt;. For example, if your KeyFile is&lt;br /&gt;//       located in the project directory, you would specify the AssemblyKeyFile&lt;br /&gt;//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]&lt;br /&gt;//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework&lt;br /&gt;//       documentation for more information on this.&lt;br /&gt;//&lt;br /&gt;[assembly: AssemblyDelaySign(false)]&lt;br /&gt;[assembly: AssemblyKeyFile("AccountManager.key")]&lt;br /&gt;[assembly: AssemblyKeyName("")]&lt;br /&gt;&lt;br /&gt;[assembly: ApplicationName( "COM+ Bank Server Account Manager" )]&lt;br /&gt;[assembly: ApplicationActivation( ActivationOption.Server )]&lt;br /&gt;&lt;br /&gt;In particular, pay attention to the fact that we specify a version number for this library using the AssemblyVersion attribute and also specify the assembly key file using the AssemblyKeyFile attribute. The ApplicationName attribute is self-explanatory. However, the attribute of special interest is the ApplicationActivation attribute. As you may know, MTS and COM+ applications may either be hosted as a Library (e.g., Activated in the Caller's process) or Server (e.g., Activated in a new instance of dllhost.exe). The default attribute is to configure your COM+ application as a Library. Here we want to explicitly set the activation option to be specified as ActivationOption.Server.&lt;br /&gt;&lt;br /&gt;6. Build the Project Files&lt;br /&gt;&lt;br /&gt;Build the files that make up the project.&lt;br /&gt;------ Rebuild All started: Project: BookKeeper, Configuration: Debug .NET ------&lt;br /&gt;&lt;br /&gt;Preparing resources...&lt;br /&gt;Updating references...&lt;br /&gt;Performing main compilation...&lt;br /&gt;&lt;br /&gt;Build complete -- 0 errors, 0 warnings&lt;br /&gt;Building satellite assemblies...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;------ Rebuild All started: Project: AccountManager, Configuration: Debug .NET ------&lt;br /&gt;&lt;br /&gt;Preparing resources...&lt;br /&gt;Updating references...&lt;br /&gt;Performing main compilation...&lt;br /&gt;&lt;br /&gt;Build complete -- 0 errors, 0 warnings&lt;br /&gt;Building satellite assemblies...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---------------------- Done ----------------------&lt;br /&gt;&lt;br /&gt;Rebuild All: 2 succeeded, 0 failed, 0 skipped&lt;br /&gt;&lt;br /&gt;7. Deploy the component as a Shared Assembly and Configure it in the COM+ Catalog&lt;br /&gt;&lt;br /&gt;After you've built the assembly, you can use the .NET Global Assembly Cache (GAC) utility to register this assembly into the GAC as shown below.&lt;br /&gt;Command Prompt&lt;br /&gt;C:\MyProjects\Cornucopia\COMplus\BankServer\AccountManager\bin\Debug&gt;gacutil /i Bank.dll&lt;br /&gt;&lt;br /&gt;Microsoft (R) .NET Global Assembly Cache Utility. Version 1.0.2914.16&lt;br /&gt;Copyright (C) Microsoft Corp. 1998-2001. All rights reserved.&lt;br /&gt;&lt;br /&gt;Assembly successfully added to the cache&lt;br /&gt;&lt;br /&gt;C:\MyProjects\Cornucopia\COMplus\BankServer\AccountManager\bin\Debug&gt;regsvcs /fc Bank.dll&lt;br /&gt;RegSvcs - .NET Services Installation Utility Version 1.0.2914.16&lt;br /&gt;Copyright (C) Microsoft Corp. 2000-2001. All rights reserved.&lt;br /&gt;&lt;br /&gt;Installed Assembly:&lt;br /&gt;Assembly: C:\MyProjects\Cornucopia\COMplus\BankServer\AccountManager\bin\Debug\Bank.dll&lt;br /&gt;Application: COM+ Bank Server Account Manager&lt;br /&gt;TypeLib: c:\myprojects\cornucopia\complus\bankserver\accountmanager\bin\debug\Bank.tlb&lt;br /&gt;&lt;br /&gt;C:\MyProjects\Cornucopia\COMplus\BankServer\AccountManager\bin\Debug&gt;&lt;br /&gt;&lt;br /&gt;Successful registration against the cache turns this component into a shared assembly. A version of this component is copied into the GAC so that even if you delete this file locally, you will still be able to run your client program.&lt;br /&gt;&lt;br /&gt;Configuring our Assembly in the COM+ Catalog&lt;br /&gt;&lt;br /&gt;Configuring a .NET assembly in the COM+ Catalog means, you need to generate a COM Type Library (tlbexp.exe), and register the type in the system registry (regasm.exe). You also have to make sure that you enter the right information into the COM+ Catalog (RegDB). Instead of using all these tools individually, the .NET SDK provides an additional tool called the Register Services utility (regsvcs.exe). This utility simplifies the process by making sure that all required details are taken care of in a single step. It performs the following functions:&lt;br /&gt;&lt;br /&gt;    * Our Assembly is loaded into memory&lt;br /&gt;    * Out Assembly is registered (e.g., just like using regasm.exe)&lt;br /&gt;    * A COM Type Library (.tlb file) is generated and registered (e.g., just like using tlbexp.exe)&lt;br /&gt;    * The generated COM Type Library is installed in the specified COM+ Application&lt;br /&gt;    * Our Components are configured according to the attributes that are specified in the type definitions&lt;br /&gt;&lt;br /&gt;If you notice carefully, when we use the regsvcs.exe utility, we specify the /fc option (find or create) to instruct the tool to build a new COM+ application if one does not currently exist.&lt;br /&gt;&lt;br /&gt;The Component Services Explorer&lt;br /&gt;&lt;br /&gt;Once you have done all this, you can open up the Windows 2000 Component Services Explorer and discover that your .NET Assembly is now recognized as valid COM+ Application.&lt;br /&gt;&lt;br /&gt;While you explore the various property windows for this COM+ Application, you realize that the various attributes that you specified in the C# class have been used to configure our component in the COM+ Catalog. Right Click the Component and check out the Activation tab for example as shown in the screen shot below.&lt;br /&gt;&lt;br /&gt;The above settings have been automatically configured based on the following class-level attributes that you set programmatically in your original C# class from lines 82-88 in the source code above.&lt;br /&gt;&lt;br /&gt;  /// Configure component's object pooling&lt;br /&gt;  [ ObjectPooling( MinPoolSize = 5, MaxPoolSize = 10, CreationTimeout = 20 ) ]&lt;br /&gt;  /// Specify COM+ Context Attributes&lt;br /&gt;  [ MustRunInClientContext( false ) ]&lt;br /&gt;  /// Enable event tracking&lt;br /&gt;  [ EventTrackingEnabled( true ) ]&lt;br /&gt;  /// Enable JITA for the component&lt;br /&gt;  [ JustInTimeActivation( true ) ]&lt;br /&gt;  /// Enable Construction String Support for the component&lt;br /&gt;  [ ConstructionEnabled( Enabled=true, Default="Gopalan's Bank Server" ) ]&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Now you need to build a client application that can access this COM+ Server component.&lt;br /&gt; COM+&lt;br /&gt; Building a complete COM+ Server component using C# and .NET&lt;br /&gt; Building a COM+ Client using C# and .NET&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-4220722150326512881?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/4220722150326512881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/com-and-net-framework-building-complete.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/4220722150326512881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/4220722150326512881'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/02/com-and-net-framework-building-complete.html' title='COM+ and the .NET Framework Building a complete COM+ Server component using C# and .NET'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-6578584395509982775</id><published>2010-01-31T22:05:00.000-08:00</published><updated>2010-01-31T22:11:48.004-08:00</updated><title type='text'>JavaScript Virtual Keyboard</title><content type='html'>Introduction&lt;br /&gt;&lt;br /&gt;Imagine that you are sitting in a London Internet cafe wishing to write an e-mail to your family living in Athens. It's good if someone in your family speaks English. If not, where would you find a keyboard with a Greek layout? I'm sure you can recall a dozen situations when you thought, "I wish I had another keyboard." This article presents the Virtual Keyboard that solves this usability problem. The design task for it can be specified as follows:&lt;br /&gt;&lt;br /&gt;    * Allow text input from computers without the user's native language layout installed, therefore allowing the creation of national and multilingual interfaces -- e.g. Web-based e-mail -- that can be used worldwide.&lt;br /&gt;    * Allow text input from computers without keyboards or with sensor screens -- hand-held PCs, smartphones, etc. -- or with remote controls such as mice, e-pens, etc. being the only input devices.&lt;br /&gt;    * Protect users from keylogger-type spyware.&lt;br /&gt;&lt;br /&gt;Installation of the Virtual Keyboard requires a casual knowledge of HTML and JavaScript. To be able to fine-tune the script, you must be familiar with W3C DOM Level 1, CSS Level 1 and the DOM/Microsoft Internet Explorer event model. Virtual Keyboard is an open-source script distributed under the zlib/libpng license.&lt;br /&gt;Setup&lt;br /&gt;&lt;br /&gt;Six easy steps:&lt;br /&gt;&lt;br /&gt;   1.&lt;br /&gt;&lt;br /&gt;      Download the source archive.&lt;br /&gt;   2.&lt;br /&gt;&lt;br /&gt;      Choose your installation:&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            vkboard.js (1-vkboard folder in the archive) is the primary script. Full keyboard is simulated as follows:&lt;br /&gt;&lt;br /&gt;            Screenshot - jvk-full.jpg&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            vkboards.js (2-vkboard_slim folder) is almost the same as previous, but the language menu, which can be accessed by clicking on the red rectangle in the left-bottom corner of the keyboard, has a special configuration. The cells are arranged in rows, not as a simple drop-down menu like in the previous variant.&lt;br /&gt;&lt;br /&gt;            Screenshot - jvk-slim.jpg&lt;br /&gt;&lt;br /&gt;            This installation is recommended if you're short on space (UMPC, touchscreen kiosk, etc.) or if you have 4 or more layouts installed.&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            vnumpad.js (3-numpad_full folder) is the numpad part of the keyboard.&lt;br /&gt;&lt;br /&gt;            numpad variant&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            vatmpad.js (4-numpad_atm folder) is a stripped numpad that contains only the Enter and number keys.&lt;br /&gt;&lt;br /&gt;            numpad_atm variant&lt;br /&gt;   3.&lt;br /&gt;&lt;br /&gt;      Include a reference to the chosen script file in your HTML page:&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      &lt;HTML&gt;&lt;br /&gt;          &lt;HEAD&gt;&lt;br /&gt;&lt;br /&gt;             &lt;SCRIPT type="text/javascript" src="vkboard.js"&gt;&lt;/SCRIPT&gt;&lt;br /&gt;&lt;br /&gt;             ...&lt;br /&gt;&lt;br /&gt;          &lt;/HEAD&gt;&lt;br /&gt;       ...&lt;br /&gt;&lt;br /&gt;      Note that for each type of installation, two script files are available:&lt;br /&gt;          * vkboard.js /vkboards.js /vnumpad.js /vatmpad.js are the original script. If you wish to change the script or just want to learn how it works, this is the file for you to look at.&lt;br /&gt;          * vkboardc.js /vkboardsc.js /vnumpadc.js /vatmpadc.js is a compressed version of the script, respectively 30.5%/30.5%/39.8%/39.5% smaller than the original. This is the file you should use on the Web.&lt;br /&gt;   4.&lt;br /&gt;&lt;br /&gt;      Define a callback function:&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      &lt;HTML&gt;&lt;br /&gt;          &lt;HEAD&gt;&lt;br /&gt;&lt;br /&gt;              &lt;SCRIPT type="text/javascript" src="vkboard.js"&gt;&lt;/SCRIPT&gt;&lt;br /&gt;&lt;br /&gt;              &lt;SCRIPT&gt;&lt;br /&gt;&lt;br /&gt;              // Minimal callback function:&lt;br /&gt;              function keyb_callback(char)&lt;br /&gt;              {&lt;br /&gt;                  // Let's bind vkeyboard to the &lt;TEXTAREA&gt;&lt;br /&gt;&lt;br /&gt;                  // with id="textfield":&lt;br /&gt;                  var text =&lt;br /&gt;                      document.getElementById("textfield"), val = text.value;&lt;br /&gt;&lt;br /&gt;                  switch(ch)&lt;br /&gt;                  {&lt;br /&gt;                      case "BackSpace":&lt;br /&gt;                      var min=(val.charCodeAt(val.length - 1) == 10) ? 2 : 1;&lt;br /&gt;                      text.value = val.substr(0, val.length - min);&lt;br /&gt;                      break;&lt;br /&gt;&lt;br /&gt;                     case "Enter":&lt;br /&gt;                         text.value += "\n";&lt;br /&gt;                         break;&lt;br /&gt;&lt;br /&gt;                     default:&lt;br /&gt;                         text.value += ch;&lt;br /&gt;                  }&lt;br /&gt;              }&lt;br /&gt;&lt;br /&gt;              &lt;/SCRIPT&gt;&lt;br /&gt;&lt;br /&gt;          &lt;/HEAD&gt;&lt;br /&gt;          ...&lt;br /&gt;&lt;br /&gt;      The callback function must have one or two parameters. The first parameter is mandatory and accepts a string value returned by the vkeyboard script. The second parameter is optional and accepts the id of the container of the vkeyboard that called the callback. It may be useful if you bind a single callback function to multiple vkeyboards. Note that this is the most basic callback function. An example of a more advanced code snippet is given later.&lt;br /&gt;   5.&lt;br /&gt;&lt;br /&gt;      Define a container for the keyboard, which must be an empty DIV or SPAN.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;       &lt;HTML&gt;&lt;br /&gt;&lt;br /&gt;          ...&lt;br /&gt;&lt;br /&gt;          &lt;BODY&gt;&lt;br /&gt;&lt;br /&gt;              ...&lt;br /&gt;&lt;br /&gt;              &lt;TEXTAREA id="textfield" rows="10" cols="50"&gt;&lt;/TEXTAREA&gt;&lt;br /&gt;&lt;br /&gt;              &lt;DIV id="keyboard"&gt;&lt;/DIV&gt;&lt;br /&gt;&lt;br /&gt;          &lt;/BODY&gt;&lt;br /&gt;&lt;br /&gt;      &lt;/HTML&gt;&lt;br /&gt;&lt;br /&gt;   6.&lt;br /&gt;&lt;br /&gt;      Finally, show the keyboard.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;       &lt;BODY onload="new VKeyboard("keyboard", keyb_callback);"&gt;&lt;br /&gt;&lt;br /&gt;       &lt;!-- VKeyboard is shown on load, bound to container with&lt;br /&gt;            id="keyboard" and with callback function "keyb_callback" --&gt;&lt;br /&gt;&lt;br /&gt;      Of course, the creation of VKeyboard -- numpad: VNumpad, ATM-style numpad: VATMpad -- can be used anywhere a JavaScript code can be.&lt;br /&gt;&lt;br /&gt;API&lt;br /&gt;&lt;br /&gt;The VKeyboard constructor has a myriad of parameters to help you control its look and feel. Here is the full list, together with parameter defaults.&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;var vkb =&lt;br /&gt;    new VKeyboard("keyboard",   // container's id, mandatory&lt;br /&gt;                  keyb_callback,// reference to callback function, mandatory&lt;br /&gt;                                // (this &amp; following parameters are optional)&lt;br /&gt;                  true,         // create the arrow keys or not?&lt;br /&gt;                  true,         // create up and down arrow keys?&lt;br /&gt;                  false,        // reserved&lt;br /&gt;                  true,         // create the numpad or not?&lt;br /&gt;                  "",           // font name ("" == system default)&lt;br /&gt;                  "14px",       // font size in px&lt;br /&gt;                  "#000",       // font color&lt;br /&gt;                  "#F00",       // font color for the dead keys&lt;br /&gt;                  "#FFF",       // keyboard base background color&lt;br /&gt;                  "#FFF",       // keys' background color&lt;br /&gt;                  "#DDD",       // background color of switched/selected item&lt;br /&gt;                  "#777",       // border color&lt;br /&gt;                  "#CCC",       // border/font color of "inactive" key&lt;br /&gt;                                // (key with no value/disabled)&lt;br /&gt;                  "#FFF",       // background color of "inactive" key&lt;br /&gt;                                // (key with no value/disabled)&lt;br /&gt;                  "#F77",       // border color of language selector's cell&lt;br /&gt;                  true,         // show key flash on click? (false by default)&lt;br /&gt;                  "#CC3300",    // font color during flash&lt;br /&gt;                  "#FF9966",    // key background color during flash&lt;br /&gt;                  "#CC3300",    // key border color during flash&lt;br /&gt;                  false,        // embed VKeyboard into the page?&lt;br /&gt;                  true,         // use 1-pixel gap between the keys?&lt;br /&gt;                  0);           // index (0-based) of the initial layout&lt;br /&gt;&lt;br /&gt;Please be careful when upgrading vkeyboard from earlier versions. Always check the number/flow of the parameters. VNumpad and VATMpad have a limited set of parameters:&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;var vkb =&lt;br /&gt;    new VNumpad("numpad",     // container's id, mandatory&lt;br /&gt;                pad_callback, // reference to the callback function, mandatory&lt;br /&gt;                "",           // font name ("" == system default)&lt;br /&gt;                              // (this and following parameters are optional)&lt;br /&gt;                "14px",       // font size in px&lt;br /&gt;                "#000",       // font color&lt;br /&gt;                "#FFF",       // keyboard base background color&lt;br /&gt;                "#FFF",       // keys' background color&lt;br /&gt;                "#777",       // border color&lt;br /&gt;                true,         // show key flash on click? (false by default*)&lt;br /&gt;                "#CC3300",    // font color for flash event&lt;br /&gt;                "#FF9966",    // key background color for flash event&lt;br /&gt;                "#CC3300",    // key border color for flash event&lt;br /&gt;                false,        // embed VNumpad into the page?&lt;br /&gt;                true);        // use 1-pixel gap between the keys?&lt;br /&gt;&lt;br /&gt;Note that although "flash switch" is off by default, it is switched on in all of the provided samples. VKeyboard has the following public methods:&lt;br /&gt;&lt;br /&gt;    * Show: Shows or hides the whole vkeyboard. It has a single optional parameter, a boolean value that states whether to show or hide.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      vkb.Show(true);  // Shows the vkeyboard&lt;br /&gt;      vkb.Show(false); // Hides the vkeyboard&lt;br /&gt;      vkb.Show();      // Shows the vkeyboard again. Action is by default.&lt;br /&gt;&lt;br /&gt;    * ShowNumpad (full and slim variants only): Shows or hides the numpad. It has a single optional parameter, a boolean value that dictates whether to show or hide.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      vkb.ShowNumpad(true);  // Shows the numpad&lt;br /&gt;      vkb.ShowNumpad(false); // Hides the numpad&lt;br /&gt;      vkb.ShowNumpad();      // Shows the numpad again. This action is by default.&lt;br /&gt;&lt;br /&gt;    * """"set-param""""&gt;SetParameters: Allows you to adjust vkeyboard parameters at runtime. The function accepts an even number of values in pairs: the vkeyboard parameter name and parameter value.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      // Adjusting single parameter:&lt;br /&gt;      vkb.SetParameters("font-color", "#F0A050");&lt;br /&gt;      // Adjusting two parameters at once:&lt;br /&gt;      vkb.SetParameters("font-name", "Arial", "font-color", "#F0A050");&lt;br /&gt;&lt;br /&gt;      Valid parameter names are:&lt;br /&gt;          o callback - callback function reference. Valid parameter value: reference to any function with 1 or 2 formal parameters&lt;br /&gt;          o font-name - name of keyboard font. Valid parameter value: font name or empty string (= default font)&lt;br /&gt;          o font-size - font size in pixels. Valid parameter value: font size in pixels&lt;br /&gt;          o font-color - font color. Valid parameter value here and further on: string in format of #xxxxxx or #xxx, where x is any valid hexadecimal digit&lt;br /&gt;          o dead-color - color of the dead keys&lt;br /&gt;          o base-color - color of the keyboard base&lt;br /&gt;          o key-color - color of the keys&lt;br /&gt;          o selection-color - color of: selected item in the language menu or active modifier key&lt;br /&gt;          o border-color - color of the key border&lt;br /&gt;          o inactive-border-color - border color of the disabled key&lt;br /&gt;          o inactive-key-color - background color of the disabled key&lt;br /&gt;          o lang-cell-color - border color of the language menu item&lt;br /&gt;          o click-font-color - border color of the language menu item&lt;br /&gt;          o click-key-color - border color of the language menu item&lt;br /&gt;          o click-border-color - border color of the language menu item&lt;br /&gt;          o show-click - show key flash on click. Valid parameter value: true or false&lt;br /&gt;          o layout - index (0-based integer) of the layout to switch to. Use it to programmatically switch layouts&lt;br /&gt;&lt;br /&gt;Test Suite&lt;br /&gt;&lt;br /&gt;The script comes with the following samples:&lt;br /&gt;&lt;br /&gt;   1.&lt;br /&gt;&lt;br /&gt;      1-edit-simple.html: The most basic installation of the JavaScript Virtual Keyboard.&lt;br /&gt;   2.&lt;br /&gt;&lt;br /&gt;      2-edit-full.html: Almost the same as above, but the keyb_callback function is not so simple as it was. While simple installation only appends or deletes characters from the end of the text in a TEXTAREA, this sample allows you to edit text in the way you're used to with any other text processor. This sample shows how the JavaScript Virtual Keyboard should normally be used. All other samples are derived from this one.&lt;br /&gt;   3.&lt;br /&gt;&lt;br /&gt;      3-edit-translator.html: This one is useful if you do have the keyboard, but it doesn't have your native layout on its keys. Simply run this installation, switch vkeyboard to your native layout and type with a real keyboard, not a mouse. The script will substitute the typed characters with those chosen in vkeyboard.&lt;br /&gt;   4.&lt;br /&gt;&lt;br /&gt;      4-test-change.html: Sample illustrates the use of the SetParameters API. Watch how vkeyboard changes its color.&lt;br /&gt;   5.&lt;br /&gt;&lt;br /&gt;      5-test-fly.html: Sample shows how to handle multiple INPUT fields with a single vkeyboard.&lt;br /&gt;   6.&lt;br /&gt;&lt;br /&gt;      6-test-fly-anonym.html: Almost the same as above, but INPUT fields are allowed to omit the id property. Can be very useful for introducing vkeyboard into existing sites/pages where page changes are undesirable.&lt;br /&gt;   7.&lt;br /&gt;&lt;br /&gt;      7-test-any-css.html: Sample shows how to set the vkeyboard font size with units other than pixels. A special function, convert_to_px, is used to convert arbitrary unit strings to pixel-based values. The following units are allowed: px, %, em, ex, pt, pc, cm, mm and in. Note that the convert_to_px function is still quite experimental. The main problem is that only the Microsoft Internet Explorer browser provides a way -- via the window.screen.logicalXDPI property -- to retrieve the current screen DPI setting, which is used to convert from absolute to relative length units. With any other browser, only px, %, em and ex can be used safely. A "usual" setting of 96 dots per inch -- quite common for Windows machines -- is used if other length units are specified.&lt;br /&gt;   8.&lt;br /&gt;&lt;br /&gt;      8-test-scale.html: This sample shows how to sidestep the font scaling problem in Mozilla and Microsoft Internet Explorer browsers. The problem with Microsoft Internet Explorer is that it only zooms, i.e. changes font size, on elements that do not have the font-size style set explicitly. The Mozilla browser has a similar problem: it does change the font-size, but does not change the dimensions of the text's container element. In this sample, script tracks the changes to the base font-size and uses the SetParameters API to appropriately scale the vkeyboard layout. This sample should be viewed only in Mozilla (Firefox) and Microsoft Internet Explorer. Opera browser implements a smart zoom -- i.e. it just zooms the entire page -- and thus does not suffer from the problem. You can also overcome this trouble with one of the Microsoft Internet Explorer's wrapper browsers. For example, MyIE2 (Maxthon) also implements a smart zoom. There are also rumors that the Firefox 3 browser will feature an Opera-like page zoom behaviour.&lt;br /&gt;&lt;br /&gt;Note that all of the above samples can be found in the vkboard folder of the source archive. Variants other than the full keyboard are not provided with the full test suite, only with a single sample that shows the most simple installation of every variant.&lt;br /&gt;Creating Your Own Language Layout&lt;br /&gt;&lt;br /&gt;Two easy steps:&lt;br /&gt;&lt;br /&gt;    * Append the avail_langs array with a two-member array consisting of the language abbreviation -- usually an ISO 639-1 language code -- and the layout name written in that language, using Unicode hex values where required.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      avail_langs:&lt;br /&gt;          [["Us", "English (US)"],&lt;br /&gt;              ["Ca", "Canadian"],&lt;br /&gt;              ["Ru", "&amp;#x0420;&amp;#x0443;&amp;#x0441;" +&lt;br /&gt;              "&amp;#x0441;&amp;#x043A;&amp;#x0438;&amp;#x0439;"],&lt;br /&gt;              ["De", "Deutsch"],&lt;br /&gt;              ["Fr", "Fran&amp;#x00E7;ais"],&lt;br /&gt;              ["Es", "Espa&amp;#x00F1;ol"],&lt;br /&gt;              ["It", "Italiano"],&lt;br /&gt;              ["Cz", "&amp;#x010C;esky"],&lt;br /&gt;              ["El", "&amp;#x0388;&amp;#x03BB;&amp;#x03BB;" +&lt;br /&gt;              "&amp;#x03B7;&amp;#x03BD;&amp;#x03B1;&amp;#x03C2;"],&lt;br /&gt;              ["He", "&amp;#x05E2;&amp;#x05D1;&amp;#x05E8;&amp;#x05D9;&amp;#x05EA;"]];&lt;br /&gt;&lt;br /&gt;    * Define "normal" and, optionally, the "Caps Lock"ed, "Shift"ed, "AltGr"ed and "AltGr+Shift"ed arrays. The following rules apply:&lt;br /&gt;          o Each array's name must begin with the language abbreviation and the underscore symbol.&lt;br /&gt;          o Names of arrays with values representing symbols for a keyboard with "Caps Lock" pressed must end with caps.&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            // Czech layout:&lt;br /&gt;            Cz_caps: ["&amp;#x003B;", ... , "&amp;#x002D;"];&lt;br /&gt;&lt;br /&gt;          o Names of arrays with values representing symbols for a keyboard with "Shift" pressed must end with shift.&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            Cz_shift: ["&amp;#x00BA;", ... , "&amp;#x005F;"];&lt;br /&gt;&lt;br /&gt;          o Names of arrays with values representing symbols for a keyboard with "AltGr" pressed must end with alt_gr.&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            Cz_alt_gr: [..., "&amp;#x0021;", "&amp;#x002F;"];&lt;br /&gt;&lt;br /&gt;          o Names of arrays with values representing symbols for a keyboard with the "AltGr" and "Shift" keys pressed must end with alt_gr_shift.&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            Cz_alt_gr_shift: ["&amp;#x007E;", ... , "&amp;#x003F;"];&lt;br /&gt;&lt;br /&gt;          o Names of arrays with values representing symbols for a keyboard's normal condition -- i.e. with no modifier keys pressed -- must end with normal.&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            Cz_normal: ["&amp;#x003B;", ... , "&amp;#x002D;"];&lt;br /&gt;&lt;br /&gt;          o Each array must have exactly 48 entries, each containing either the hexadecimal value of the appropriate symbol or, in the case of a dead key, the array consisting of the hex value for this dead symbol and the name of one of the following predefined arrays:&lt;br /&gt;                + Acute (?)&lt;br /&gt;                + Breve (?)&lt;br /&gt;                + Caron (?)&lt;br /&gt;                + Cedilla (?)&lt;br /&gt;                + Circumflex (^)&lt;br /&gt;                + DialytikaTonos (?, dialytika tonos, combined acute + umlaut)&lt;br /&gt;                + DotAbove (?, dot above)&lt;br /&gt;                + DoubleAcute (?, double acute)&lt;br /&gt;                + Grave (`)&lt;br /&gt;                + Ogonek (?)&lt;br /&gt;                + RingAbove (°, ring above)&lt;br /&gt;                + Tilde (~)&lt;br /&gt;                + Umlaut (?)&lt;br /&gt;&lt;br /&gt;            Also, the Macron (¯) diacritic array is available via the macron.txt file in the 1-vkboard folder of the archive. It is not included to the main script because no layout I know implements it as a dead key.&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            Cz_alt_gr: [["&amp;#x0060;", "Grave"], // dead key&lt;br /&gt;                "&amp;#x0021;", ...                // simple key&lt;br /&gt;&lt;br /&gt;          o Arrays are mapped to the layout according to the following illustration, where numbers within cells are the array indices.&lt;br /&gt;&lt;br /&gt;            array-to-key mapping&lt;br /&gt;          o The "normal" array is mandatory; others are optional.&lt;br /&gt;&lt;br /&gt;      The following layouts are built into the full and slim keyboard variants. The number/index next to the layout name is the layout index in the IBM Globalization database:&lt;br /&gt;          o English (US International) - 103P&lt;br /&gt;          o Canadian (multilingual standard) - taken from Wikipedia article on keyboard layouts&lt;br /&gt;          o German - 129&lt;br /&gt;          o French - 189&lt;br /&gt;          o Spanish - 173&lt;br /&gt;          o Italian - 142&lt;br /&gt;          o Russian - 443&lt;br /&gt;          o Czech - 243&lt;br /&gt;          o Greek - 319&lt;br /&gt;          o Hebrew - 212&lt;br /&gt;&lt;br /&gt;      24 other layouts are available in a separate layout pack that can be found in the 5-layout_pack folder in the archive. It includes:&lt;br /&gt;          o European:&lt;br /&gt;                + Bulgarian - 442&lt;br /&gt;                + Czech - alternative variant of Bohemica.com&lt;br /&gt;                + Danish - 159 and 281&lt;br /&gt;                + Dutch - 143&lt;br /&gt;                + Estonian - 454&lt;br /&gt;                + Finnish - 153&lt;br /&gt;                + Hungarian - 208&lt;br /&gt;                + Icelandic - 197&lt;br /&gt;                + Latvian - 455&lt;br /&gt;                + Lithuanian - 456&lt;br /&gt;                + Macedonian - 449&lt;br /&gt;                + Norwegian - 155 and 281N&lt;br /&gt;                + Polish - 214 and 457 (programmer's)&lt;br /&gt;                + Portuguese - 163&lt;br /&gt;                + Romanian - 446&lt;br /&gt;                + Serbian - 450 (cyrillic script)&lt;br /&gt;                + Serbo-Croatian/Slovene - 234 (Latin script)&lt;br /&gt;                + Slovak - 245&lt;br /&gt;                + Swedish - 285&lt;br /&gt;                + Ukrainian - 465&lt;br /&gt;          o Asian:&lt;br /&gt;                + Arabic - 470&lt;br /&gt;&lt;br /&gt;      Please see the readme.txt file in the 5-layout_pack folder in the archive for instructions regarding these layouts.&lt;br /&gt;&lt;br /&gt;Creating Your Own Keyboard Layout&lt;br /&gt;&lt;br /&gt;You may wish to create a custom key layout. There are two ways to achieve this:&lt;br /&gt;&lt;br /&gt;   1.&lt;br /&gt;&lt;br /&gt;      Use atm.js as a template; it is the simplest script of four. See the numpad_atm folder in the archive for more details. In short, the script flow is as follows:&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            Create the outer box:&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            var initX = 0, initY = 0;&lt;br /&gt;&lt;br /&gt;            ...&lt;br /&gt;&lt;br /&gt;            var kb = document.createElement("DIV");&lt;br /&gt;            ct.appendChild(kb);&lt;br /&gt;&lt;br /&gt;            ct.style.display = "block";&lt;br /&gt;            ct.style.position = "absolute";&lt;br /&gt;            ct.style.top = initY + "px", ct.style.left = initX +"px";&lt;br /&gt;&lt;br /&gt;            kb.style.position = "relative";&lt;br /&gt;            kb.style.top = "0px", kb.style.left = "0px";&lt;br /&gt;            kb.style.border = "1px solid " + bc;&lt;br /&gt;&lt;br /&gt;            var kb_main = document.createElement("DIV");&lt;br /&gt;            kb.appendChild(kb_main);&lt;br /&gt;&lt;br /&gt;            kb_main.style.position = "relative";&lt;br /&gt;            kb_main.style.width = "1px";&lt;br /&gt;            kb_main.style.cursor = "default";&lt;br /&gt;            kb_main.style.backgroundColor = bkc;&lt;br /&gt;&lt;br /&gt;            ...&lt;br /&gt;&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            Create the keys with the _setup_key method:&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            var kb_pad_7 = this._setup_key(kb_main, "1px",&lt;br /&gt;                "1px", cp, cp, bc, c, lh, fs);&lt;br /&gt;            kb_pad_7.sub.innerHTML = "7";&lt;br /&gt;            kb_pad_7.sub.id = container_id + "___pad_7";&lt;br /&gt;&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            Route all output to the _generic_callback_proc method. For the VATMpad object, this is done in the _set_key_state method while refreshing the layout:&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            this._setup_event(key_sub, 'mousedown',&lt;br /&gt;                this._generic_callback_proc);&lt;br /&gt;&lt;br /&gt;          *&lt;br /&gt;&lt;br /&gt;            Invoke the callback function. This happens when the user "presses" a "key":&lt;br /&gt;            Collapse&lt;br /&gt;&lt;br /&gt;            _generic_callback_proc: function(event)&lt;br /&gt;            {&lt;br /&gt;                ...&lt;br /&gt;&lt;br /&gt;                if(val &amp;&amp; vkboard.Callback)&lt;br /&gt;                    vkboard.Callback(val);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Sample layout&lt;br /&gt;   2.&lt;br /&gt;&lt;br /&gt;      Hire me. It is the best way to get a custom modification of a JavaScript Virtual Keyboard, specialized tuning and optimizations, pro support and fast, authoritative answers to JavaScript programming questions.&lt;br /&gt;&lt;br /&gt;Call from Beyond&lt;br /&gt;&lt;br /&gt;One natural feature that all users expect from a text field is the ability to edit the text at any position within a field. However, it is impossible to do so with a function described earlier, which only appends symbols to or removes from the end of the text. The following script is an attempt to write a compatible callback function to fulfill the described task. It is largely based on the discussion in the thescripts.com forum.&lt;br /&gt;Collapse&lt;br /&gt;&lt;br /&gt;&lt;HEAD&gt;&lt;br /&gt;    &lt;SCRIPT type="text/javascript"&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;    var opened = false,&lt;br /&gt;        insertionS = -1,  // selection start&lt;br /&gt;&lt;br /&gt;        insertionE =  0;  // selection end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    var userstr = navigator.userAgent.toLowerCase();&lt;br /&gt;    var safari = (userstr.indexOf('applewebkit') != -1);&lt;br /&gt;    var gecko  = (userstr.indexOf('gecko') != -1) &amp;&amp; !safari;&lt;br /&gt;    var standr = gecko || window.opera || safari;&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    // Advanced callback function:&lt;br /&gt;    //&lt;br /&gt;&lt;br /&gt;    function keyb_callback(ch)&lt;br /&gt;    {&lt;br /&gt;        var val = text.value;&lt;br /&gt;&lt;br /&gt;        switch(ch)&lt;br /&gt;        {&lt;br /&gt;            case "BackSpace":&lt;br /&gt;            if(val.length)&lt;br /&gt;            {&lt;br /&gt;                var span = null;&lt;br /&gt;&lt;br /&gt;                if(document.selection)&lt;br /&gt;                span = document.selection.createRange().duplicate();&lt;br /&gt;&lt;br /&gt;                if(span &amp;&amp; span.text.length &gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    span.text = "";&lt;br /&gt;                    getCaretPositions(text);&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                deleteAtCaret(text);&lt;br /&gt;            }&lt;br /&gt;            break;&lt;br /&gt;&lt;br /&gt;            case "&lt;":&lt;br /&gt;                if(insertionS &gt; 0)&lt;br /&gt;                setRange(text, insertionS - 1, insertionE - 1);&lt;br /&gt;            break;&lt;br /&gt;&lt;br /&gt;            case "&gt;":&lt;br /&gt;                if(insertionE &lt; val.length)&lt;br /&gt;                setRange(text, insertionS + 1, insertionE + 1);&lt;br /&gt;            break;&lt;br /&gt;&lt;br /&gt;            case "/\\":&lt;br /&gt;                if(!standr) break;&lt;br /&gt;                var prev  = val.lastIndexOf("\n", insertionS) + 1;&lt;br /&gt;                var pprev = val.lastIndexOf("\n", prev - 2);&lt;br /&gt;                var next  = val.indexOf("\n", insertionS);&lt;br /&gt;&lt;br /&gt;                if(next == -1) next = val.length;&lt;br /&gt;                var nnext = next - insertionS;&lt;br /&gt;&lt;br /&gt;                if(prev &gt; next)&lt;br /&gt;                {&lt;br /&gt;                    prev  = val.lastIndexOf("\n", insertionS - 1) + 1;&lt;br /&gt;                    pprev = val.lastIndexOf("\n", prev - 2);&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                // number of chars in current line to the left of the caret:&lt;br /&gt;                var left = insertionS - prev;&lt;br /&gt;&lt;br /&gt;                // length of the prev. line:&lt;br /&gt;                var plen = prev - pprev - 1;&lt;br /&gt;&lt;br /&gt;                // number of chars in the prev. line to&lt;br /&gt;                // the right of the caret:&lt;br /&gt;                var right = (plen &lt;= left) ? 1 : (plen - left);&lt;br /&gt;&lt;br /&gt;                var change = left + right;&lt;br /&gt;                setRange(text, insertionS - change, insertionE - change);&lt;br /&gt;&lt;br /&gt;            break;&lt;br /&gt;&lt;br /&gt;            case "\\/":&lt;br /&gt;                if(!standr) break;&lt;br /&gt;&lt;br /&gt;                var prev  = val.lastIndexOf("\n", insertionS) + 1;&lt;br /&gt;                var next  = val.indexOf("\n", insertionS);&lt;br /&gt;                var pnext = val.indexOf("\n", next + 1);&lt;br /&gt;&lt;br /&gt;                if( next == -1)  next = val.length;&lt;br /&gt;                if(pnext == -1) pnext = val.length;&lt;br /&gt;&lt;br /&gt;                if(pnext &lt; next) pnext = next;&lt;br /&gt;&lt;br /&gt;                if(prev &gt; next)&lt;br /&gt;                prev  = val.lastIndexOf("\n", insertionS - 1) + 1;&lt;br /&gt;&lt;br /&gt;                // number of chars in current line to the left of the caret:&lt;br /&gt;                var left = insertionS - prev;&lt;br /&gt;&lt;br /&gt;                // length of the next line:&lt;br /&gt;                var nlen = pnext - next;&lt;br /&gt;&lt;br /&gt;                // number of chars in the next line to the left of the caret:&lt;br /&gt;                var right = (nlen &lt;= left) ? 0 : (nlen - left - 1);&lt;br /&gt;&lt;br /&gt;                var change = (next - insertionS) + nlen - right;&lt;br /&gt;                setRange(text, insertionS + change, insertionE + change);&lt;br /&gt;&lt;br /&gt;            break;&lt;br /&gt;&lt;br /&gt;            default:&lt;br /&gt;                insertAtCaret(text,&lt;br /&gt;                   (ch == "Enter" ? (window.opera ? '\r\n' : '\n') : ch));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // This function retrieves the position (in chars, relative to&lt;br /&gt;    // the start of the text) of the edit cursor (caret), or, if&lt;br /&gt;    // text is selected in the TEXTAREA, the start and end positions&lt;br /&gt;    // of the selection.&lt;br /&gt;    //&lt;br /&gt;    function getCaretPositions(ctrl)&lt;br /&gt;    {&lt;br /&gt;        var CaretPosS = -1, CaretPosE = 0;&lt;br /&gt;&lt;br /&gt;        // Mozilla way:&lt;br /&gt;        if(ctrl.selectionStart || (ctrl.selectionStart == '0'))&lt;br /&gt;        {&lt;br /&gt;            CaretPosS = ctrl.selectionStart;&lt;br /&gt;            CaretPosE = ctrl.selectionEnd;&lt;br /&gt;&lt;br /&gt;            insertionS = CaretPosS == -1 ? CaretPosE : CaretPosS;&lt;br /&gt;            insertionE = CaretPosE;&lt;br /&gt;        }&lt;br /&gt;        // IE way:&lt;br /&gt;        else if(document.selection &amp;&amp; ctrl.createTextRange)&lt;br /&gt;        {&lt;br /&gt;            var start = end = 0;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                start =&lt;br /&gt;                    Math.abs(&lt;br /&gt;                    document.selection.createRange().moveStart("character",&lt;br /&gt;                    -10000000)); // start&lt;br /&gt;&lt;br /&gt;                if (start &gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    try&lt;br /&gt;                    {&lt;br /&gt;                        var endReal =&lt;br /&gt;                            Math.abs(&lt;br /&gt;                            ctrl.createTextRange().moveEnd("character",&lt;br /&gt;                            -10000000));&lt;br /&gt;&lt;br /&gt;                        var r = document.body.createTextRange();&lt;br /&gt;                        r.moveToElementText(ctrl);&lt;br /&gt;                        var sTest =&lt;br /&gt;                            Math.abs(r.moveStart("character", -10000000));&lt;br /&gt;                        var eTest =&lt;br /&gt;                            Math.abs(r.moveEnd("character", -10000000));&lt;br /&gt;&lt;br /&gt;                        if((ctrl.tagName.toLowerCase() != 'input') &amp;&amp;&lt;br /&gt;                            (eTest - endReal == sTest))&lt;br /&gt;                            start -= sTest;&lt;br /&gt;                    }&lt;br /&gt;                    catch(err) {}&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            catch (e) {}&lt;br /&gt;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                end =&lt;br /&gt;                    Math.abs(&lt;br /&gt;                    document.selection.createRange().moveEnd("character",&lt;br /&gt;                    -10000000)); // end&lt;br /&gt;                if(end &gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    try&lt;br /&gt;                    {&lt;br /&gt;                        var endReal =&lt;br /&gt;                            Math.abs(&lt;br /&gt;                            ctrl.createTextRange().moveEnd("character",&lt;br /&gt;                            -10000000));&lt;br /&gt;&lt;br /&gt;                        var r = document.body.createTextRange();&lt;br /&gt;                        r.moveToElementText(ctrl);&lt;br /&gt;                        var sTest =&lt;br /&gt;                            Math.abs(r.moveStart("character", -10000000));&lt;br /&gt;                        var eTest =&lt;br /&gt;                            Math.abs(r.moveEnd("character", -10000000));&lt;br /&gt;&lt;br /&gt;                        if ((ctrl.tagName.toLowerCase() != 'input') &amp;&amp;&lt;br /&gt;                            (eTest - endReal == sTest))&lt;br /&gt;                             end -= sTest;&lt;br /&gt;                    }&lt;br /&gt;                    catch(err) {}&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            catch (e) {}&lt;br /&gt;&lt;br /&gt;            insertionS = start;&lt;br /&gt;            insertionE = end&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function setRange(ctrl, start, end)&lt;br /&gt;    {&lt;br /&gt;        if(ctrl.setSelectionRange) // Standard way (Mozilla, Opera, ...)&lt;br /&gt;        {&lt;br /&gt;            ctrl.setSelectionRange(start, end);&lt;br /&gt;        }&lt;br /&gt;        else // Microsoft Internet Explorer&lt;br /&gt;        {&lt;br /&gt;            var range;&lt;br /&gt;&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                range = ctrl.createTextRange();&lt;br /&gt;            }&lt;br /&gt;            catch(e)&lt;br /&gt;            {&lt;br /&gt;                try&lt;br /&gt;                {&lt;br /&gt;                    range = document.body.createTextRange();&lt;br /&gt;                    range.moveToElementText(ctrl);&lt;br /&gt;                }&lt;br /&gt;                catch(e)&lt;br /&gt;                {&lt;br /&gt;                    range = null;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if(!range) return;&lt;br /&gt;&lt;br /&gt;            range.collapse(true);&lt;br /&gt;            range.moveStart("character", start);&lt;br /&gt;            range.moveEnd("character", end - start);&lt;br /&gt;            range.select();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        insertionS = start;&lt;br /&gt;        insertionE = end;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function deleteSelection(ctrl)&lt;br /&gt;    {&lt;br /&gt;        if(insertionS == insertionE) return;&lt;br /&gt;&lt;br /&gt;        var tmp =&lt;br /&gt;            (document.selection &amp;&amp;&lt;br /&gt;            !window.opera) ? ctrl.value.replace(/\r/g,"") : ctrl.value;&lt;br /&gt;        ctrl.value =&lt;br /&gt;            tmp.substring(0, insertionS) + tmp.substring(insertionE,&lt;br /&gt;            tmp.length);&lt;br /&gt;&lt;br /&gt;        setRange(ctrl, insertionS, insertionS);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function deleteAtCaret(ctrl)&lt;br /&gt;    {&lt;br /&gt;        if(insertionS != insertionE)&lt;br /&gt;        {&lt;br /&gt;            deleteSelection(ctrl);&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if(insertionS == insertionE)&lt;br /&gt;        insertionS = insertionS - 1;&lt;br /&gt;&lt;br /&gt;        var tmp =&lt;br /&gt;            (document.selection &amp;&amp;&lt;br /&gt;            !window.opera) ? ctrl.value.replace(/\r/g,"") : ctrl.value;&lt;br /&gt;        ctrl.value =&lt;br /&gt;            tmp.substring(0,&lt;br /&gt;            insertionS) + tmp.substring(insertionE, tmp.length);&lt;br /&gt;&lt;br /&gt;        setRange(ctrl, insertionS, insertionS);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // This function inserts text at the caret position:&lt;br /&gt;    //&lt;br /&gt;    function insertAtCaret(ctrl, val)&lt;br /&gt;    {&lt;br /&gt;        if(insertionS != insertionE) deleteSelection(ctrl);&lt;br /&gt;&lt;br /&gt;        if(isgecko &amp;&amp; document.createEvent &amp;&amp; !window.opera)&lt;br /&gt;        {&lt;br /&gt;            var e = document.createEvent("KeyboardEvent");&lt;br /&gt;&lt;br /&gt;            if(e.initKeyEvent &amp;&amp; ctrl.dispatchEvent)&lt;br /&gt;            {&lt;br /&gt;                e.initKeyEvent("keypress", // in DOMString typeArg,&lt;br /&gt;                    false,                 // in boolean canBubbleArg,&lt;br /&gt;                    true,                  // in boolean cancelableArg,&lt;br /&gt;                    null,                  // in nsIDOMAbstractView viewArg,&lt;br /&gt;                    false,                 // in boolean ctrlKeyArg,&lt;br /&gt;                    false,                 // in boolean altKeyArg,&lt;br /&gt;                    false,                 // in boolean shiftKeyArg,&lt;br /&gt;                    false,                 // in boolean metaKeyArg,&lt;br /&gt;                    null,                  // key code;&lt;br /&gt;                    val.charCodeAt(0));    // char code.&lt;br /&gt;&lt;br /&gt;                ctrl.dispatchEvent(e);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {&lt;br /&gt;            var tmp =&lt;br /&gt;                (document.selection &amp;&amp;&lt;br /&gt;                !window.opera) ? ctrl.value.replace(/\r/g,"") : ctrl.value;&lt;br /&gt;            ctrl.value =&lt;br /&gt;                tmp.substring(0,&lt;br /&gt;                insertionS) + val + tmp.substring(insertionS,&lt;br /&gt;                tmp.length);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        setRange(ctrl, insertionS + val.length, insertionS + val.length);&lt;br /&gt;    }&lt;br /&gt;    //--&gt;&lt;/SCRIPT&gt;&lt;br /&gt;&lt;br /&gt;&lt;/HEAD&gt;&lt;br /&gt;&lt;br /&gt;&lt;BODY&gt;&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    &lt;-- Don't forget this 'onclick' and 'onkeyup': --&gt;&lt;br /&gt;    &lt;TEXTAREA onkeyup="getCaretPositions(this);"&lt;br /&gt;        onclick="getCaretPositions(this);"&lt;br /&gt;&lt;br /&gt;        id="textfield" rows="12" cols="50"&gt;&lt;br /&gt;    &lt;/TEXTAREA&gt;&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;&lt;/BODY&gt;&lt;br /&gt;&lt;br /&gt;Note that the up and down arrows on a virtual keyboard work only on standards-compliant browsers! Take this into account when creating touch screen applications. You can test the above script by running the 2-edit-full.html file found in the vkboard folder of the attached archive. Basic callback is demonstrated in 1-edit-simple.html.&lt;br /&gt;Tips and Tricks&lt;br /&gt;&lt;br /&gt;Script flow is quite straightforward, so I hope it won't be hard to dive into it. Here are a couple of words on a few tricky places.&lt;br /&gt;&lt;br /&gt;    *&lt;br /&gt;&lt;br /&gt;      Event set-up. We need to handle both Microsoft Internet Explorer and W3C DOM event models:&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      _setup_event: function(elem, eventType, handler)&lt;br /&gt;      {&lt;br /&gt;          return (elem.attachEvent ? // Microsoft Internet Explorer way&lt;br /&gt;&lt;br /&gt;              elem.attachEvent("on" + eventType, handler) :&lt;br /&gt;              ((elem.addEventListener) ? // W3C way&lt;br /&gt;&lt;br /&gt;              elem.addEventListener(eventType, handler, false) : null));&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;    *&lt;br /&gt;&lt;br /&gt;      Key container set-up. Each key consists of the "outer" DIV -- where we set the top, left, width and height parameters only -- and the "inner" DIV, which accepts padding, border color and other parameters. We use such a complex construction to circumvent the box model problem of modern browsers. Note that there is the JavaScript solution. If you wish to avoid the box model problem using CSS, you may wish to see the article by Trenton Moss (see item #6).&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      _setup_key: function(parent, id, top, left, width, height,&lt;br /&gt;          text_align, line_height, font_size,&lt;br /&gt;          font_weight, padding_left, padding_right)&lt;br /&gt;      {&lt;br /&gt;          var exists = document.getElementById(id);&lt;br /&gt;&lt;br /&gt;          // Outer DIV:&lt;br /&gt;&lt;br /&gt;          var key =&lt;br /&gt;              exists ? exists.parentNode : document.createElement("DIV");&lt;br /&gt;          this._setup_style(key,&lt;br /&gt;              !exists, top, left, width, height, "absolute");&lt;br /&gt;&lt;br /&gt;          // Inner DIV:&lt;br /&gt;&lt;br /&gt;          var key_sub = exists ? exists : document.createElement("DIV");&lt;br /&gt;          key.appendChild(key_sub); parent.appendChild(key);&lt;br /&gt;&lt;br /&gt;          this._setup_style(key_sub,&lt;br /&gt;              !exists, "", "", "", line_height, "relative",&lt;br /&gt;              text_align, line_height, font_size, font_weight,&lt;br /&gt;              padding_left, padding_right);&lt;br /&gt;              key_sub.id = id;&lt;br /&gt;&lt;br /&gt;          return key_sub;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;    *&lt;br /&gt;&lt;br /&gt;      Disabling content selection. This one is very important due to the very high typing speed that some people can achieve and, as a result, the inevitable vkeyboard content selection. It can be used instead of the UNSELECTABLE (Microsoft Internet Explorer) and -moz-user-select (Gecko-based browsers) properties.&lt;br /&gt;      Collapse&lt;br /&gt;&lt;br /&gt;      this._setup_event(kb_main, "selectstart",&lt;br /&gt;          function(event)&lt;br /&gt;          {&lt;br /&gt;              return false;&lt;br /&gt;          });&lt;br /&gt;      this._setup_event(kb_main, "mousedown",&lt;br /&gt;          function(event)&lt;br /&gt;          {&lt;br /&gt;              if(event.preventDefault)&lt;br /&gt;                  event.preventDefault();&lt;br /&gt;              return false;&lt;br /&gt;          });&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-6578584395509982775?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/6578584395509982775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/01/javascript-virtual-keyboard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/6578584395509982775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/6578584395509982775'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2010/01/javascript-virtual-keyboard.html' title='JavaScript Virtual Keyboard'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-8425926417508444957</id><published>2009-12-17T02:35:00.000-08:00</published><updated>2009-12-17T02:37:50.430-08:00</updated><title type='text'>Export Excel Sheet Data into DataTable</title><content type='html'>&lt;em&gt;&lt;span style="font-family:arial;"&gt;public DataTable CreateTable()&lt;br /&gt;{&lt;br /&gt;string FilePath = Server.MapPath("~/Studentlist.xls");&lt;br /&gt;OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+FilePath+";Extended Properties=Excel 8.0");&lt;br /&gt;conn.Open();&lt;br /&gt;DataTable dbSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,null);&lt;br /&gt;if (dbSchema == null  dbSchema.Rows.Count &lt; 1)&lt;br /&gt;{&lt;br /&gt;throw new Exception("Error: Could not determine the name of the first worksheet.");&lt;br /&gt;}&lt;br /&gt;string WorkSheetName = dbSchema.Rows[0]["TABLE_NAME"].ToString();&lt;br /&gt;OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [" + WorkSheetName + "]", conn);&lt;br /&gt;DataTable dt = new DataTable();&lt;br /&gt;da.Fill(dt);&lt;br /&gt;conn.Close();&lt;br /&gt;return dt;&lt;br /&gt;}&lt;/span&gt;&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-8425926417508444957?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/8425926417508444957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/12/export-excel-sheet-data-into-datatable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/8425926417508444957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/8425926417508444957'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/12/export-excel-sheet-data-into-datatable.html' title='Export Excel Sheet Data into DataTable'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-665137706097093288</id><published>2009-12-16T22:51:00.000-08:00</published><updated>2009-12-16T22:52:49.659-08:00</updated><title type='text'>Finding a Control at RowCommand Event of a GridView</title><content type='html'>&lt;div&gt;protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;        if (e.CommandName == "Search")      //Button click is causing event fire&lt;/div&gt;&lt;div&gt;        {&lt;/div&gt;&lt;div&gt;            GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);&lt;/div&gt;&lt;div&gt;            Label lbl1 = row.FindControl("Label1") as Label;&lt;/div&gt;&lt;div&gt;            string s = lbl1.Text;&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-665137706097093288?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/665137706097093288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/12/finding-control-at-rowcommand-event-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/665137706097093288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/665137706097093288'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/12/finding-control-at-rowcommand-event-of.html' title='Finding a Control at RowCommand Event of a GridView'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-3560302135357423208</id><published>2009-11-25T02:51:00.000-08:00</published><updated>2009-11-25T03:01:34.938-08:00</updated><title type='text'>Encrypting/Decrypting any section of web.config file</title><content type='html'>&lt;strong&gt;To Encrypt on IIS&lt;/strong&gt;&lt;br /&gt;aspnet_regiis.exe -pe "[Section To Encrypt]" -app "/[Virtual Directory on IIS]"&lt;br /&gt;&lt;br /&gt;eg---&lt;br /&gt;aspnet_regiis.exe -pd "connectionStrings" -app "/vitualdirectory"&lt;br /&gt;&lt;strong&gt;To decrypt the same use de instead of pe&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-3560302135357423208?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/3560302135357423208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/11/encryptingdecrypting-any-section-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3560302135357423208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/3560302135357423208'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/11/encryptingdecrypting-any-section-of.html' title='Encrypting/Decrypting any section of web.config file'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8769773808837040573.post-8267634941221248535</id><published>2009-11-24T20:49:00.000-08:00</published><updated>2009-11-24T21:33:11.343-08:00</updated><title type='text'>Code to Open Pdf File(Download)</title><content type='html'>Code to Open pdf/doc/any file(Download)&lt;br /&gt;&lt;br /&gt;This post is for opening any document in website&lt;br /&gt;// function to open file&lt;br /&gt;protected void OpenDocument()&lt;br /&gt;{&lt;br /&gt;// Get the physical Path of the file(test.doc)&lt;br /&gt;string filepath = Server.MapPath("Document Location");&lt;br /&gt;&lt;br /&gt;// Create New instance of FileInfo class to get the properties of the file being downloaded&lt;br /&gt;FileInfo file = new FileInfo(filepath);&lt;br /&gt;&lt;br /&gt;// Checking if file exists&lt;br /&gt;if (file.Exists)&lt;br /&gt;{&lt;br /&gt;// Clear the content of the response&lt;br /&gt;Response.ClearContent();&lt;br /&gt;&lt;br /&gt;// LINE1: Add the file name and attachment, which will force the open/cance/save dialog to show, to the header&lt;br /&gt;Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);&lt;br /&gt;&lt;br /&gt;// Add the file size into the response header&lt;br /&gt;Response.AddHeader("Content-Length", file.Length.ToString());&lt;br /&gt;&lt;br /&gt;// Set the ContentType&lt;br /&gt;Response.ContentType = ReturnExtension(file.Extension.ToLower());&lt;br /&gt;&lt;br /&gt;// Write the file into the response (TransmitFile is for ASP.NET 2.0. In ASP.NET 1.1 you have to use WriteFile instead)&lt;br /&gt;Response.TransmitFile(file.FullName);&lt;br /&gt;&lt;br /&gt;// End the response&lt;br /&gt;Response.End();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;// Function to get extenstion of the file&lt;br /&gt;private string ReturnExtension(string fileExtension)&lt;br /&gt;{&lt;br /&gt;switch (fileExtension)&lt;br /&gt;{&lt;br /&gt;case ".htm":&lt;br /&gt;case ".html":&lt;br /&gt;case ".log":&lt;br /&gt;return "text/HTML";&lt;br /&gt;case ".txt":&lt;br /&gt;return "text/plain";&lt;br /&gt;case ".doc":&lt;br /&gt;return "application/ms-word";&lt;br /&gt;case ".tiff":&lt;br /&gt;case ".tif":&lt;br /&gt;return "image/tiff";&lt;br /&gt;case ".asf":&lt;br /&gt;return "video/x-ms-asf";&lt;br /&gt;case ".avi":&lt;br /&gt;return "video/avi";&lt;br /&gt;case ".zip":&lt;br /&gt;return "application/zip";&lt;br /&gt;case ".xls":&lt;br /&gt;case ".csv":&lt;br /&gt;return "application/vnd.ms-excel";&lt;br /&gt;case ".gif":&lt;br /&gt;return "image/gif";&lt;br /&gt;case ".jpg":&lt;br /&gt;case "jpeg":&lt;br /&gt;return "image/jpeg";&lt;br /&gt;case ".bmp":&lt;br /&gt;return "image/bmp";&lt;br /&gt;case ".wav":&lt;br /&gt;return "audio/wav";&lt;br /&gt;case ".mp3":&lt;br /&gt;return "audio/mpeg3";&lt;br /&gt;case ".mpg":&lt;br /&gt;case "mpeg":&lt;br /&gt;return "video/mpeg";&lt;br /&gt;case ".rtf":&lt;br /&gt;return "application/rtf";&lt;br /&gt;case ".asp":&lt;br /&gt;return "text/asp";&lt;br /&gt;case ".pdf":&lt;br /&gt;return "application/pdf";&lt;br /&gt;case ".fdf":&lt;br /&gt;return "application/vnd.fdf";&lt;br /&gt;case ".ppt":&lt;br /&gt;return "application/mspowerpoint";&lt;br /&gt;case ".dwg":&lt;br /&gt;return "image/vnd.dwg";&lt;br /&gt;case ".msg":&lt;br /&gt;return "application/msoutlook";&lt;br /&gt;case ".xml":&lt;br /&gt;case ".sdxl":&lt;br /&gt;return "application/xml";&lt;br /&gt;case ".xdp":&lt;br /&gt;return "application/vnd.adobe.xdp+xml";&lt;br /&gt;default:&lt;br /&gt;return "application/octet-stream";&lt;br /&gt;}&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8769773808837040573-8267634941221248535?l=manojpoojasharma.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manojpoojasharma.blogspot.com/feeds/8267634941221248535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/11/code-to-open-pdf-filedownload.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/8267634941221248535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8769773808837040573/posts/default/8267634941221248535'/><link rel='alternate' type='text/html' href='http://manojpoojasharma.blogspot.com/2009/11/code-to-open-pdf-filedownload.html' title='Code to Open Pdf File(Download)'/><author><name>Manoj Sharma Technology is a Boom----</name><uri>http://www.blogger.com/profile/10032995026597187555</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
