HTML /HTML5, Technical Posts

HTML5 <video> tag and my concept of Video mailing.

For the last couple of weeks I am surfing a lot for HTML5 features and whatever new features it have is really amazing. You can also find many articles on web related to the HTML5. I found this article as the best describer , html5demos. When you check new elements that added on this new HTML version , you can find the tag “video” .

The purpose of this media element/tag is to play videos or movies. Currently we use third party plug ins of Quick Time, Flash , Real Player etc to view videos on our web page.
But now with HTML5 we can directly embed videos on the web page using . This element do have “src” attribute just as in <img> tag where we can give url of the video. Currently only web browsers such as Fire Fox 3.5+ , Chrome, Safari 3+ , Opera supports the video tag. For IE users its not currently available, but soon it will get supported from IE9 .

Here, the idea that I want to express is something related to Video Mailing. This means that every email provider can give video messaging service too , when HTML5 become popular. My idea can be more elaborated like this , there will be a “Create a video mail” link on our email account page . When clicking on this link, cam and mic on the client machine will get activated[same as in the FaceBook’s “Create Video” option.] .The video will be saved on the server and intimation will be send to the receiver’s inbox after clicking on the send button. When receiver clicks on the video message, it will start rendering as the video on the page. The purpose is to convey the messages with emotions , gestures, actions etc. I feel there are some advantages and disadvantages for this approach.

  Advantages

  • Conveying messages with expressions, emotions etc
  • Authentication of the sender can be 100% assured, since it is a video email.
  • No need to go for big big email drafting to convey a small message.
  • Clarity of message will be more in Video Mail.

  Disadvantages

  • More server space will be utilized than the regular text messages
  • Instant messaging need hardwares like camera ,mic on the sender’s machine.
  • More bandwidth is required for receiving video mail than the text emails 

Kindly comment on my idea of Video mailing and lets have discussion on the same . Thanks

C# 4.0, Technical Posts

Lets move to C# 4.0

Some features like Dynamic programming,Optional arguments,Named arguments

Dynamic Programming :

This is the major feature of C# 4.0. In the first look it looks something like our previous “var” type of C#3.0 or regular object type that we have with C#,root Type of .NET . But its not like that. Actually when you assigns a variable of Type “dynamic” and use its properties/methods ,compiler doesn’t mind it at compile time. Means, no method/property resolution takes part in compile time and it will take care all of those things at run time. By these words dont think “dynamic” is dynamic type ,its a static type only.

The below mentioned code is a small example for the dynamic programming.

using System;
using System.Text;

namespace DynamicType
{
	class Program
	{
		static void Main(string[] args)
		{

			Mathematics objmathematics = new Mathematics();
			dynamic objdynamic = objmathematics;

			
			double resAdd= objdynamic.add(3,2);
			Console.WriteLine(resAdd.ToString());

			//The method "subtract" is not present in the Class Mathematics.
			double resSub = objdynamic.subtract(3, 2);
			Console.WriteLine(resSub.ToString());

			Console.ReadLine();
		}
	}

	class Mathematics
	{ 
	
		public Mathematics()	{}


		public double add(double a, double b)
		{
			return a + b;		
		}
	}
}

On compiling the above code, the build will succeed with a smile. But at run time it will break at code line number 18. Because the function “subtract” that is trying to resolve is not present in the Mathematics Class and method “add” will pass through because it is available.

The DLR, Dynamic Language Runtime is responsible for this dynamic programming capability . Basically its built on the top of the CLR to make the dynamic languages such as IronPython, IronRuby etc to get supported. To know more about DLR please go to this link

The main use of this dynamic programming is to support the compilation during interfacing of our managed code with COM , Javascript DOM or any dynamic languages.


Optional and Named arguments:

Now we can have optional values for the C# methods . We can set default values for the arguments and can pass the values during the method call according to our need.Also we can call each parameter by its name , not by its position as earlier. This is called Named argument

It will be like this :

public double GetPNRValue(double a=1,double b=0,double c=1)
		{
			return (a * b / c);
		}

And when we call this method, we can pass arguments like this

double resPNR = objdynamic.GetPNRValue(2,c:0);			

It says that “a” is 2, “b” can be the optional argument and “c” be zero . Here “c” is the Named argument.

CodeProject, Sharepoint

Cascading dropdowns in InfoPath from SharePoint.

It is very common for every developer to have a situation to  develop cascading dropdowns during their development life. It can be Category –Product scenario, Country-State scenario etc.  Here the case is something different; cascading is not on regular ASP.NET Page or not a simple web part. But it’s on a InfoPath form…..!  You will ask, what makes the difference?  I say, if the InfoPath is browser enabled, the filter option of the InfoPath won’t work or it won’t support.  Any how we developers have to accomplish this cascading task. Below, i have a scenario and its solution step by step.

Scenario:  I have two SharePoint lists “Categories “and “Products”. “Categories” SharePoint list have a column named “Category” and “Product” SharePoint list have 2 columns – Product and Category, out of which Category is a look up column from “Categories” SharePoint List. Now we have to develop a InfoPath form with 2 dropdowns, Categories and Products and we need to make it work in a cascading style. Means when the user selects a particular category on the Categories dropdown, related set of products should be populated on the Products dropdown. This is the scenario.

Solution: Follow the simple steps to accomplish this task.

  1. Open Microsoft InfoPath 2007 from Start à All Programs à Microsoft Office.
  2. Create a blank InfoPath form template using the option “Design a Form Template”. Don’t forget to check the option “Enable Browser Compatible Features” while creating the blank template.
  3. Now we have a blank InfoPath form in front of us. Drag and Drop two dropdowns from the toolbox and name them as Categories and Products.
  4. After step 3 , we need to populate the dropdowns with data. For that we need to create data connections with in the InfoPath form. “Categories” dropdown can be populated directly from the “Categories” SharePoint list. But Products dropdown can’t be populated from products SharePoint list, because its need to populated according to the selected category. In the next 2 steps we will create data connections for the dropdowns.
  5. In this step we will create data connection for the Categories dropdown. Select “Dataconnections… ” option from the “Tools” menu [menu available on the top portion] of the InfoPath form. From the “Dataconnections” window click add and on the DataConnection wizard select “Create new dataconnection” option with “Receive Data” Selection. On the “select the source of your data” step ,  go with the option “Sharepoint Library or List”. The coming steps of the wizard are self informative and proceed with selection of our Categories SharePoint List. Once we finish with the DataConnection wizard steps, Bind the created Categories dataconnection  with “Categories” Dropdown by right clicking on the control and from “Dropdown  list properties”  , select “Look up values from the external datasources” option. Now there will be a selection  with available dataconnections. Select our categories dataconnection and select category field  for  “Entries” option. Check on the InfoPath preview, whether data is populated correctly or not. So population of the  Categories dropdown is over.
  1. In this step we will create dataconnection for the Products dropdown. Here  we have to do some more work to create Products dataconnection. This is the portion we have to look on. Before going to create dataconnection for Products, we have to create a webservice that have function which return set  of  products according to the category passed. So, Create a WSPBuilder project and  add a Webservice item to the project  from WSPBuilder project templates or you can go with other webservice creation techniques and deploy it to the sharepoint site. Usually I create SharePoint components with the WSPBuilder . If it is with WSPBuilder, packaging and deployment is quite easy.

Give a user-friendly name to the webservice and in the code behind of the Webservice file add the following piece of code.

[WebMethod]
        public DataSet GetProducts(string Category)
        {

            DataSet dsProducts = new DataSet();
            DataTable dtProducts = new DataTable();
            DataColumn dcCategory = new DataColumn("Category");
            DataColumn dcProduct = new DataColumn("Product");
            dtProducts.Columns.Add(dcCategory);
            dtProducts.Columns.Add(dcProduct);

            SPSite site = SPContext.Current.Site;
            SPList list = site.OpenWeb().Lists["Products"];
            SPQuery query = new SPQuery();
            query.Query = @"<Where>
      <Eq>
         <FieldRef Name='Category' />
         <Value Type='Lookup'>"+ Category  +@"</Value>
      </Eq>
   </Where>";
            SPListItemCollection itemCol = list.GetItems(query);

            DataRow drCategory;
            foreach (SPListItem item in itemCol)
            {
                drCategory = dtProducts.NewRow();
                drCategory[dcCategory] = Convert.ToString(item["Category"]);
                drCategory[dcProduct] = Convert.ToString(item["Product"]);
                dtProducts.Rows.Add(drCategory);
            }

            dsProducts.Tables.Add(dtProducts);
            return dsProducts;
  }

This webservice method will return set of products for the given category. Build this project, build the WSP and deploy to the sharepoint site. After the deployment of the WSP , we can find the webservice in the _layouts virtual directory of the sharepoint site on the IIS. It will look like this http://localhost:5050/_layouts/CascadingDDLService.asmx .   Browse that .asmx  file and check whether  the “GetProducts” webservice method  is working on invoking. If it is working, we can proceed with it during the creation of “Products” dataconnection.

Now we can start creating dataconnection for Products. Follow the procedures mentioned on the step 5,till you reach “select the source of your data” step on the dataconnection wizard. On this step you have to select “Web service” option rather than “Sharepoint Library or List” option that we have taken on the step 5. After selecting  “Web Service” option , on this next step it will ask us to provide the webservice URL. Provide our webservice url that we have deployed before, it will give set of web- methods in the web service, in our case it will be only method ,“GetProducts”. Click next , it will ask for the  default parameter values and go on with the steps with clicking Next. But on the last step we have to consider one important thing , uncheck the option “Automatically retreive data when form is opened.” and click Finish to end dataconnection wizard.Now the Products dataconnection is created and we can bind this dataconnection to the Product dropdown list. Follow the same procedures mentioned on the step 5 to bind the dataconnection on the dropdown.

  1. Next step is to create the “Rules” for the Categories Dropdown. This step is very important for the cascading to work.
    • Right click on the Categories dropdown, select “Rules” option. From the rules window, click “Add” button to add a rule for the categories dropdown.
    • On the click of the “Add” button, you will see a window like this

Name the rule with a user-friendly name. Click on the “Set Condition” button and set a condition as per the below mentioned image.


We need to set the condition that Rule need to shoot when Categories is not blank.

    • After setting the Condition we can set the “Actions” for that rule.Here we need to set 3 actions. Click on the “Add Action” button to set an action.
    • In first action we will set the Products Field previously set value to Null. Select “Set a field’s value” from the action’s dropdown.For that select Products Field from main datasource and click OK without setting the value.

    • On the second action we need to set the Category parameter for the “GetProducts”  dataconnection, which is a secondary datasource. Select “Set a field’s value” from the action’s dropdown. In the Field section select Category parameter

and set its value to the Main datasource Category Field.

    • In the third action we will populate the “GetProducts” datasource . For that Select “Query using a dataconnection” from action’s dropdown and select “GetProducts” dataconnection from Data connection’s dropdown.

Finally the Rule window will be like this

Now save InfoPath Form and publish to any SharePoint site. Browse the InfoPath form from any of your browser, cascading of dropdown will work with charm…. 🙂

CodeProject, Sharepoint

Asynchronous Sharepoint List Insert / Update.

Hello SharePoint developers… This time I have a new stuff to a share with you all. Two weeks back I met with one of my friends, who is also working as Software developer in SharePoint Technology. In between our talks he explained about a technical issue that he is facing in his project. The issue was regarding the use of AJAX in MOSS 2007. Actually his requirement is to update a SharePoint List asynchronously through a web part and he was using ASP.NET AJAX ScriptManager, UpdatePanel to accomplish this task. But it gives some cross browser issues, JavaScript issues like “ScriptResource.axd” file issue etc. I have also read that there are some issues of ASP.NET AJAX with MOSS 2007. Any how that night I also sat down along with him to find a solution. After a few trouble shooting and “googling” we come to a conclusion that it can’t be done with a small span of time. We started thinking for a new solution and into my mind it came like shooting star. “ICallbackEventHandler”…….. Yes, we started creating a new web part that implements the interface ICallbackEventHandler.

Here we can look into some small piece of code that explains “How to update a SharePoint List asynchronously using ICallbackEventHandler?”. This post assumes that readers have idea regarding the SharePoint Web Part development. Please go through the following steps to know how things are done.

This is simple example where we will add SP List Item to a SP List asynchronously through a Webpart.

1. Create a SharePoint Custom List having 2 columns [Name, Age] on your SharePoint Site.

2. Create a new SharePoint WSP Project from your Visual Studio IDE. [Please install WSPBuilder from CodePlex, if you don’t have a WSPBuilder Template ].

3. Add a Web Part Feature into the project from the “Add new Item” option on the created project.

4. Switch to the webpart code .cs file . This will be under the WebPartCode folder in the project, if we use the WSPBuilder Template.

5. Utilize the CreateChildControls() Method to develop the UI for the webpart with 2 Textboxes and a button. One textbox is for input value of the “Name” and other for “Age”. The button will be used to Submit the input values.The below mentioned will be the code inside the CreateChildControls() Method.

protected override void CreateChildControls()
        {
                try
                {
                    base.CreateChildControls();

                    txtName = new TextBox();
                    txtName.ID = "txtName";

                    txtAge = new TextBox();
                    txtAge.ID = "txtAge";

                    btnSubmit = new HtmlButton();
                    btnSubmit.ID = "btnSubmit";
                    btnSubmit.InnerText = "Submit";
                    btnSubmit.Attributes.Add("onclick", "javascript:CallServer2();");

                    Table tbl = new Table();
                    TableRow tr1 = new TableRow();
                    TableRow tr2 = new TableRow();
                    TableRow tr3 = new TableRow();

                    TableCell cell11 = new TableCell();
                    TableCell cell12 = new TableCell();
                    TableCell cell21 = new TableCell();
                    TableCell cell22 = new TableCell();
                    TableCell cell31 = new TableCell();
                    TableCell cell32 = new TableCell();

                    tr1.Cells.Add(cell11);
                    tr1.Cells.Add(cell12);
                    tr2.Cells.Add(cell21);
                    tr2.Cells.Add(cell22);
                    tr3.Cells.Add(cell31);
                    tr3.Cells.Add(cell32);

                    cell11.Text = "Name";
                    cell12.Controls.Add(txtName);

                    cell21.Text = "Age";
                    cell22.Controls.Add(txtAge);

                    cell32.Controls.Add(btnSubmit);

                    tbl.Rows.Add(tr1);
                    tbl.Rows.Add(tr2);
                    tbl.Rows.Add(tr3);

                    this.Controls.Add(tbl);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

6. Implement the ICallbackEventHandler interface to the webpart class. Implementation of this interface will add functions, 1. RaiseCallbackEvent 2. GetCallbackResult.

RaiseCallbackEvent – This function will be used to write code logic to update/insert the item to the Sharepoint List. This method have a parameter of type string which bring client side input data to the server side.

GetCallBackResult – This function is used to return the server side feedback to the client side as string.

Along with these 2 server side functionalities there are 2 client side JavaScript functions also needed for the orchestra. These Javascript functions are used to Call Server [here we will create JS function CallServer] functionalities from client side and for receiving the server feedback[JS function name will be ReceiveServerdata]. These JS functionalities need to register to Page Client Script block as follows.

protected override void OnLoad(EventArgs e)
        {

                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    ClientScriptManager cm = Page.ClientScript;
                    String cbReference = cm.GetCallbackEventReference(this, "arg",
                        "ReceiveServerData", "");
                    String callbackScript = "function CallServer(arg, context) {" +
                        cbReference + "; }";
                    cm.RegisterClientScriptBlock(this.GetType(),
                        "CallServer", callbackScript, true);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

7. Also we need to write our own JavaScript function [SetInputValues]to create appended a global string variable with all input values delimited by semi colon “;”. This global string variable is passed through the CallServer JS Function to reach the server side.
To accomplish this client side functionalities cleaner we will create a JS Function CallServer2 to call previously mentioned CallServer JS function and SetInputValues JS function. This CallServer2 JS function will be called on the onclick of the submit button.

//global variable
            var inputValues;

            function SetInputValues()
            {

                inputValues='';
                var txtName = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtName');
                var txtAge = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtAge');

                var Name=txtName.value;
                var Age=txtAge.value;

                inputValues=Name+';'+Age;

            }
            function CallServer2()
            {
                SetInputValues();
                CallServer(inputValues,'');

            }

            function ReceiveServerData(arg, context)
            {
                        alert(arg);
            }

All these JS Functions will be written on the code file of the webpart as a string variable and these JS functions are registered to the page on the OnInit event.

private string jsString = @"
            //global variable
            var inputValues;

            function SetInputValues()
            {

                inputValues='';
                var txtName = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtName');
                var txtAge = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtAge');

                var Name=txtName.value;
                var Age=txtAge.value;

                inputValues=Name+';'+Age;

            }
            function CallServer2()
            {
                SetInputValues();
                CallServer(inputValues,'');

            }

            function ReceiveServerData(arg, context)
            {
                        alert(arg);
            }
           ";
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.ClientScript.RegisterStartupScript(this.GetType(), "callback", jsString, true);
        }

8. From the Server side we can take this input string[global variable “inputValues”] values through the previously mentioned RaiseCallbackEvent method’s parameter and we split this string with semicolon to get the array of input values to insert into the SP List.

 public void RaiseCallbackEvent(string eventArgument)
        {

            char[] delimiter = new char[1];
            delimiter[0] = Convert.ToChar(";");
            string[] inputData = new string[2];
            inputData = eventArgument.Split(delimiter);

            string siteUrl = "http://galaxian:5050/default.aspx";
            string libName = "NameList";
            // Open the site
            using (SPSite site = new SPSite(siteUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {

                    SPList list = web.Lists[libName];
                    SPListItem item = list.Items.Add();
                    item["Title"] = inputData[0];
                    item["Age"] = inputData[1];
                    item.Update();

                }
            }
        }

9. After the inserting the item we can intimate the client side using the GetCallbackResult() method

public string GetCallbackResult()
        {
            return "Data inserted successfully...!";
        }

This message will be displayed as a JS alert after the insertion of the data. This server side feedback will be received by the ReceiveServerData() JS Function as mentioned on the Step 7.

The whole Code file for the webpart will look as below.

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint;

namespace Asynchronous_SharepointListUpdate
{
    [Guid("6e22a748-4b74-481f-8b08-98106f869cf3")]
    public class Asynchronous_SPWebPart : Microsoft.SharePoint.WebPartPages.WebPart, ICallbackEventHandler
    {
        private bool _error = false;
        private string _myProperty = null;

        public Asynchronous_SPWebPart()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        TextBox txtName;
        TextBox txtAge;
        HtmlButton btnSubmit;

        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
                try
                {
                    base.CreateChildControls();

                    txtName = new TextBox();
                    txtName.ID = "txtName";

                    txtAge = new TextBox();
                    txtAge.ID = "txtAge";

                    btnSubmit = new HtmlButton();
                    btnSubmit.ID = "btnSubmit";
                    btnSubmit.InnerText = "Submit";
                    btnSubmit.Attributes.Add("onclick", "javascript:CallServer2();");

                    Table tbl = new Table();
                    TableRow tr1 = new TableRow();
                    TableRow tr2 = new TableRow();
                    TableRow tr3 = new TableRow();

                    TableCell cell11 = new TableCell();
                    TableCell cell12 = new TableCell();
                    TableCell cell21 = new TableCell();
                    TableCell cell22 = new TableCell();
                    TableCell cell31 = new TableCell();
                    TableCell cell32 = new TableCell();

                    tr1.Cells.Add(cell11);
                    tr1.Cells.Add(cell12);
                    tr2.Cells.Add(cell21);
                    tr2.Cells.Add(cell22);
                    tr3.Cells.Add(cell31);
                    tr3.Cells.Add(cell32);

                    cell11.Text = "Name";
                    cell12.Controls.Add(txtName);

                    cell21.Text = "Age";
                    cell22.Controls.Add(txtAge);

                    cell32.Controls.Add(btnSubmit);

                    tbl.Rows.Add(tr1);
                    tbl.Rows.Add(tr2);
                    tbl.Rows.Add(tr3);

                    this.Controls.Add(tbl);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

        private string jsString = @"
            //global variable
            var inputValues;

            function SetInputValues()
            {

                inputValues='';
                var txtName = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtName');
                var txtAge = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtAge');

                var Name=txtName.value;
                var Age=txtAge.value;

                inputValues=Name+';'+Age;

            }
            function CallServer2()
            {
                SetInputValues();
                CallServer(inputValues,'');

            }

            function ReceiveServerData(arg, context)
            {
                        alert(arg);
            }
           ";
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.ClientScript.RegisterStartupScript(this.GetType(), "callback", jsString, true);
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {

                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    ClientScriptManager cm = Page.ClientScript;
                    String cbReference = cm.GetCallbackEventReference(this, "arg",
                        "ReceiveServerData", "");
                    String callbackScript = "function CallServer(arg, context) {" +
                        cbReference + "; }";
                    cm.RegisterClientScriptBlock(this.GetType(),
                        "CallServer", callbackScript, true);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }

        #region ICallbackEventHandler Members

        public string GetCallbackResult()
        {
            return "Data inserted successfully..!";
        }

        public void RaiseCallbackEvent(string eventArgument)
        {

            char[] delimiter = new char[1];
            delimiter[0] = Convert.ToChar(";");
            string[] inputData = new string[2];
            inputData = eventArgument.Split(delimiter);

            string siteUrl = "http://galaxian:5050/default.aspx";
            string libName = "NameList";
            // Open the site
            using (SPSite site = new SPSite(siteUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {

                    SPList list = web.Lists[libName];
                    SPListItem item = list.Items.Add();
                    item["Title"] = inputData[0];
                    item["Age"] = inputData[1];
                    item.Update();

                }
            }
        }

        #endregion
    }
}

This was the workaround that we have done for the asynchronous insert on the sharepoint list.

Hope you have enjoyed this post…Thanks for reading.

ASP.NET, CodeProject

GridView Pagination issue when dynamically added….!

Hello ASP.NET Developers… Today I came across a small issue which killed large amount of my development time. The issue was a little tricky between the lines of code. I have an ASP.NET gridview which is dynamically (on the fly) created on my page. When I am inserting 2 lines of code  just for allowing the gridview pagination, code breaks at runtime giving  a NullReferenceException .

Cause of the issue :  i was adding the dynamically created  gridview(object) into page’s control collection after the databinding. This works fine if there is no pagination code added. But if there is code which allows pagination for the dynamically added gridview, this gridview should be added to the page’s control collection before the databinding.

Please see the below mentioned code blocks for the difference.

This piece of code will give the Null Reference Exception:

GridView gvDepartment = new GridView ();
gvDepartment.ID = "gvDepartment";

gvDepartment.AllowPaging = true;
gvDepartment.PageSize = 4;

gvDepartment.DataSource = GetDepartmentRows ();
gvDepartment.DataBind ();

this.form1.Controls.Add ( gvDepartment );

This is the perfect code:

        GridView gvDepartment = new GridView ();
        gvDepartment.ID = "gvDepartment";

        gvDepartment.AllowPaging = true;
        gvDepartment.PageSize = 4;

	/* Need to add gridview into controls collection before databind,if there is pagination */
        this.form1.Controls.Add ( gvDepartment );

        gvDepartment.DataSource = GetDepartmentRows ();
        gvDepartment.DataBind ();

NB: Obviously PageIndexChanging Event handling is needed. But this post is about the exception thrown while dynamically adding gridview. So the readers please keep in mind to add pageindexchanging event should be handled.
I hope this post helped you or given a nice thought. Thanks for reading.Please comment if you feel any issues on the same.

ASP.NET, CodeProject, Technical Posts

How to send XML data to a Webpage using “POST” Method.

Recently I came across an interesting requirement to send XML data to a particular URL using POST, means i need to post some XML data to a URL. I came to answer within a couple hrs of “googling” and R&D. Below mentioned is the sample code that I have created to explain the technique. Scenario defines here explains data sending between 2 websites, one is requestor website, which send xml POST data and other is responder website, which collect data from requestor website.

The step by step instructions are as follows.

  1. Open a Microsoft Visual Studio instance and from the file menu select the option to create ASP.NET website/web application. Create two websites using this option and name these websites with user-friendly names such as Requestor and Responder. For easier developer view make these websites under a single visual studio solution.
  2. By default there will be a default.aspx page inside each website. Just delete that page, we can create new pages for our sample
  3. Add a new page to the Requestor website. We can name this page as requestor.aspx. Our aim is to post XML data from requestor.aspx to the responder.aspx of the Responder website. Using the responder page we will save that XML data to a text (.txt) file. Add a new page to the Responder website name this page as requestor.aspx.
  4. Host Responder website on your local IIS.
  5. Select the Requestor website. Design the Requestor page as shown on the image below.

Page design of the Requestor page
One main Multiline textbox for XML Data, a Textbox for entering  URL to send the XML data and  a Button

6.Handle the click event of the button, add the following the piece of code to that event.

protected void btnPostXml_Click(object sender, EventArgs e)
{
        System.Net.WebRequest req = null;
        System.Net.WebResponse rsp = null;
        try
        {
            string uri = txtURI.Text;
            req = System.Net.WebRequest.Create ( uri );
            req.Method = "POST";
            req.ContentType = "text/xml";
            System.IO.StreamWriter writer = new System.IO.StreamWriter ( req.GetRequestStream () );
            writer.WriteLine (  txtXMLData.Text );
            writer.Close ();
            rsp = req.GetResponse ();
        }
        catch
        {
            throw;
        }
        finally
        {
            if (req != null) req.GetRequestStream ().Close ();
            if (rsp != null) rsp.GetResponseStream ().Close ();
        }
}

7.Select the Responder website. Take the Page Load event of the Responder.aspx page. Add the following piece of code to the Load event.

protected void Page_Load(object sender, EventArgs e)
    {
        Page.Response.ContentType = "text/xml";
        System.IO.StreamReader reader = new System.IO.StreamReader ( Page.Request.InputStream );
        String xmlData = reader.ReadToEnd ();
        System.IO.StreamWriter SW;
        SW = File.CreateText ( Server.MapPath(".")+@"\"+ Guid.NewGuid () + ".txt" );
        SW.WriteLine ( xmlData );
        SW.Close ();
    }

Here we are reading the stream of data from the page request and writing that data to a text file.
Note: On this sample i have made the ValidateRequest=”false” for the requestor to accept the XML Data on the form post.

This methodology can also be used as a CALLBACK to a URL with some data post.

Take the code sample(VS 2010 needed)

Thanks for reading this post. Please comment if you have any issues/doubt with the code.

Technical Posts

WebControl/Custom Control’s events not working?.

Few days back i had a strange issue during my webcontrol development .The issue was that child control events like button click’s , DropDownlist’s  SelectedIndexChanged are not working. On a simple glance everything  was done as per the regular flow of coding… I search on Bing,Live,Google etc…. Didnt find much effective solution on the first day.. On a deep dive to webcontrol development i found some articles,books,blogs that  mentioning about the influence of implementation INamingContainer interface to the WebControl Class. Actually this interface does nothing when we do the implementation . Means we except must implemented functions from the interface. But in case INamingContainer there is nothing like that… its  a marker interface.By this interface it allows unique naming of the dynamically generated server control instances within the WebControl.       

Here i will explain the creation of a simple webcontrol. So  HOW  TO CREATE  A  WEBCONTROL?         

 1. Open Visual Studio and  Create a blank solution.(File menu –> New Project –> On left side Project Types tree, expand Other Project Types node, select Visual Studio Solutions, Select Blank Solution from right side pane.). Name the Solution  as WebControls         

2.Add a Class library Project to this solution.Name this as WebControlAssembly.       

 3.Add  the Reference of System.Web to the library. This reference is done  to get the System.Web.UI.WebControls, System.Web.UI namespaces inside the project.         

4.Rename the default added Class file to TextButtonControl.cs.         

5. Delete all the default code from the new class file and paste the below mentioned lines of code to the class file.         

using System;
using System.Web.UI;
using System.Web.UI.WebControls; 
namespace TextButtonWebControl
{
 //*** INamingContainer is a must.Any control that implements this interface creates a new namespace in which all child control ID-
 //attributes are guaranteed to be unique within an entire application.
 //The marker provided by this interface allows unique naming of the dynamically generated server control instances within the-
 //Web server controls that support data binding
 public class TextButtonControl : WebControl, INamingContainer
 {
  private TextBox txtControl;
  private Button btnControl;
  private Table tbl;// Master container of button and textbox.   

  //public event for handling click  of the button
  public event EventHandler BtnClick;   

  public TextButtonControl()
  { }   

  protected override void CreateChildControls()
  {     

   txtControl = new TextBox();
   txtControl.ID = "txtControl";   

   btnControl = new Button();
   btnControl.ID = "btnControl";
   btnControl.Text = "Submit";
   btnControl.CausesValidation = false;
   btnControl.Click += new EventHandler(btnControl_Click);   

   tbl = new Table();
   tbl.Width = Unit.Percentage(25);
   tbl.ID = "tbl";   

   TableRow tblrow = new TableRow();
   tblrow.ID = "tblrow";
   tblrow.Width = Unit.Percentage(100);   

   TableCell tblCell0 = new TableCell();
   tblCell0.ID = "tblCell0";
   tblCell0.Controls.Add(txtControl);
   tblCell0.HorizontalAlign = HorizontalAlign.Left;   

   TableCell tblCell1 = new TableCell();
   tblCell1.ID = "tblCell1";
   tblCell1.HorizontalAlign = HorizontalAlign.Left;
   tblCell1.Controls.Add(btnControl);   

   tblrow.Cells.Add(tblCell0);
   tblrow.Cells.Add(tblCell1);
   tbl.Rows.Add(tblrow);
   Controls.Add(tbl);   

   base.CreateChildControls();
  }   

  //Button Click event to call public event.
  void btnControl_Click(object sender, EventArgs e)
  {
   this.ControlText = txtControl.Text;
   if (BtnClick != null)
   {
    BtnClick(sender, e);
   }   

  }   

  public string ControlText
  { get; set; }   

 }
}   

    6. Just compile the Class the library project. Build Succeeded…….! ???. Webcontrol is ready now…..           

 7. In this step we will add a New Website to this solution. Right click on the newly created website , click Add reference option and on the Add reference window click  Projects tab . On this tab select Webcontrol Library project, here in this example it is WebControlAssembly. Click OK. The reference of the Webcontrol is added to website. Now we can add the webcontrol to the webpage.Follow this register tag  to  register this control to page  .  <%@ Register Assembly=”WebControlAssembly” Namespace=”TextButtonWebControl” TagPrefix=”Tc” %>           

This  mark-up will add the control to the page. You can see the custom event “OnBtnClick” to handle the button click of the  WebControl.         

<Tc:TextButtonControl ID=”TextButtonControl1″ runat=”server” OnBtnClick=”TextButtonControl1_BtnClick” />  
 Below mentioned is event handling for the OnBtnClick Event.    

 protected void TextButtonControl1_BtnClick(object sender, EventArgs e)  

   Response.Write(TextButtonControl1.ControlText); }    

 Please read the step 8 to get the proper understanding of code.      

  

 8.  I will explain the above piece of code . This webcontrol is intended to create a small  table layout which have a TextBox and Button. The TextButtonControl class is inherited from WebControl and it also implementated INamingContainer. The reason for this interface implemenatation  is mentioned on the top of the post. The CreateChildControls method is overrided to create the instances of the child controls like button,textbox,Table and to control collection. Here Table is the master container for the button and textbox to maintain the layout of the webcontrol. The button and texbox is added to the Table’s object instance and Table’s object instance is added to the Control Collection.Please check the CreateChildControls method for the code.      We have handled the button’s click event and this event can be  handled from webpage where this control is used.There is a public event called BtnClick which is called on the button’s click event and event is raised from webpage. This is very useful to handle the child control event from the webpage where the webcontrol is used.       

  There is ControlText get-set property to get or to set the Text value of the Textbox Control of the webcontrol.Using this property we can receive the text value from the textbox of the webpage where the control is  used.      

Hope this artice helped you…  if any suggestions or feedback please leave a comment.Thanks for reading.