Error while using Cascading DropDownList with AjaxControlToolkit

Challenge:

While Implementing Cascading drop down we faced following error:
Error: Error: Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback or callback argument.  Event validation is enabled using in configuration or <%@ Page EnableEventValidation=”true” %> in a page.
For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.
If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Source File: http://OURHOSTNAME/ScriptResource.axd?d=3VKrK_7HFd3y9jouIWGfT0xsPUpPWsWH7SoDffy51nkCL04Nc90n7Ein_H4RztbD1yDGLUI-Zz15U7kAewqh2RASTjlbBKaWvjs5uaWOHUtXwDXAq22ilJZaUX8Iu9W_HK9ITwo1waG12DLEuDRxogn2m-XmlhYYCX-66L12c6NnjBet1rAqn3G588BxLbc40&t=348b0da
Line: 1534
Yes, you are right. Our DropDownLists were wrapped within Update Panel. You are also facing similar error? Then this post is for you:

Solution:

We did a quick search and found following links:
http://ajaxcontroltoolkit.codeplex.com/workitem/8103
http://forums.asp.net/t/1903036.aspx?how+to+set+EnableEventValidation+false+from+userControl+DotNetNuke
From Link what we understood is that, It is a BUG of AjaxControlToolkit and to resolve  this you’ve to try following workaround:
[sourcecode language=”csharp”]
protected void Page_Init(object sender, EventArgs e)<br clear="none" />        {        <br clear="none" />            Page.EnableEventValidation = false;<br clear="none" />        }
[/sourcecode]
So, Just use this code where you are facing this challenge. We were seeing it from one of the Sublayout. So, we kept it there and it worked!
Happy Coding! 🙂

Country specific phone number validation with ASP.NET

Challenge:

Before few weeks back, I have been assigned a task, Where I need to validate a phone number. Sound simple? Yes it is! But I needed to do it country specific? Now, how it sounds?
Basically, User will have a list of countries to select. And based on his/her country selection he/she will provide phone number and we should validate based on country selection. Sounds challenging? That’s how life should be!
You are also working on such thing and looking for a way to get out of it? Then this post is for you!

Solution:

As per every software engineer’s practice, I started my research and our common friend. Google presented option of using Regex for each country. But it sounded bit complex to me. Then continued my research and found a super hero!
LibPhoneNumberIt’s a library from Google champs to validate phone number (Excerpt from their main page — Google’s common Java, C++ and Javascript library for parsing, formatting, storing and validating international phone numbers. The Java version is optimized for running on smartphones, and is used by the Android framework since 4.0 (Ice Cream Sandwich).)
And after reading this description, It attracted me! (To you as well?). It’s good we found HERO. But how to fit him in our picture? Then after doing bit of a research found this two nice components:

  1. http://phoneformat.com/ — Javascript version of Google’s libphonenumber library
  2. http://libphonenumber.codeplex.com/ – C# port of Google’s libphonenumber

This was a Eureka moment. Just plugged both of this libraries with CustomValidator and you are done! So, here’s how CustomValidator clientside and server-side functions looks like:
Blogs
SUGIN
[sourcecode language=”html”]
<asp:<span class="hiddenSpellError">TextBox ID="txtPhone"  runat="server" />
<asp:<span class="hiddenSpellError">RequiredFieldValidator ID="reqTxtPhone"
runat="server" ErrorMessage="Please enter a phone number" Text="*" ControlToValidate="txtPhone"
></asp:RequiredFieldValidator>
<asp:<span class="hiddenSpellError">CustomValidator ID="custPhoneNumber" runat="server"
OnServerValidate="PhoneNumberValidate"
ErrorMessage="Please enter valid phone number"
Text="*"
ControlToValidate="txtPhone"
ClientValidationFunction="PhoneNumberValidate"
/>
[/sourcecode]

[sourcecode language=”javascript”]
/*
This function will be used to validate
Phone Number client side by CustomValidator
*/
function PhoneNumberValidate(oSrc,args) {
// Call PhoneFormat.JS function which takes Phone Number and Country Code
// in ISO 3166-1 format
var isValidNumberOrNot = isValidNumber(txtPhone.value, ddlcountry.value);
arg.IsValid = isValidNumberOrNot;
}
[/sourcecode]
[sourcecode language=”csharp”]
/// <summary>
/// This function will be used to validate
/// Phone Number server side by CustomValidator
/// </summary>
/// <param name="source">Source</param>
/// <param name="args">Arguments</param>
protected void PhoneNumberValidate(object source, ServerValidateEventArgs args)
{
PhoneNumberUtil phoneUtil = PhoneNumberUtil.Instance;
// TODO : EXCEPTION HANDLING
string countryCode = ddlcountry.SelectedItem.Value
if (string.IsNullOrEmpty(countryCode))
{
args.IsValid = false;
}
else
{
PhoneNumber phoneNumber = phoneUtil.Parse(txtPhone.Text, countryCode);
bool isValidNumber = phoneNumber.IsValidNumber;
args.IsValid = isValidNumber;
}
}
</span></span></span>
[/sourcecode]
Just a note : LibPhoneNumber accepts country code in ISO 3166-1 format. But if you’ve drop down Text and Value both in full form e.g. “India” and you need to pass it as “IN” and If it’s not possible to do any change at your DropDown value level then you can use function, Which has been submitted at — https://github.com/albeebe/phoneformat.js/issues/9 It converts CountryName to CountryCode
Happy Phone Number Validation! 🙂

Uploadify (Session and authentication) with ASP.NET

Challenge:

Sorry, comrades for not sharing anything with you since so long. But was bit occupied with other stuff, and as told you earlier that currently my main focus is on my Sitecore blog and yes, with your good wishes and god’s grace — got awarded as Sitecore MVP for the year of 2013! – Thank you!
Before couple of months back, we were trying to incorporate Uploadify [http://www.uploadify.com/documentation/] in to our solution. And while working on that we came across with Flash session bug, due to use Session, authentication and authorization — it means if your user is logged in and if your file upload operation wants that only logged in users can upload file then it won’t work with Uploadify by default. Don’t worry, we have a way to get out of it!

Solution:

I asked solution of this challenge to our common friend — Google, and found really interesting links:
http://joncahill.zero41.com/2009/11/problems-with-uploadify-aspnet-mvc-and.html

“Basically the issue is with flash where it will ignore the browser’s session state and grab the cookies from IE, which is a known and active bug. This means that both Chrome and Firefox won’t work with Uploadify and authorisation because flash will send no cookies! It also means it is entirely possible for it to have previously work for me while testing because I probably also had a IE window open and logged in while testing, which would have given me a valid cookie.”

http://trycatchfail.com/blog/post/2009/05/23/using-flash-with-aspnet-mvc-and-authentication.aspx

There is a well-known bug in Flash that causes it to completely ignore the browser’s session state when it makes a request.  Instead, it either pulls cookies from Internet Explorer or just starts a new session with no cookies.  GOOD CALL, ADOBE.  And when I say this bug is well-known, I mean it was reported in Flash 8.  It’s still sitting in the Adobe bug tracker.  It has been triaged, it seems to have high priority, yet it remains unfixed.  Again, GREAT job, Adobe.

http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx
http://stackoverflow.com/questions/1729179/uploadify-session-and-authentication-with-asp-net-mvc
Big thanks to all these article writers. Because it only helped us to find a solution. Using this solutions we were able to make session working. But authentication and membership information was not working . But we modified a bit in Global.asax and it started working. So, let me share a final solution with you:
1.  Pass session related information from your upload page in your upload call:
Just a note : This javascript code also covers other challenges as well (Which are not in scope of this article. But you may find it helpful!) e.g. passing dynamic data via onUploadStart, sending formdata via settings, showing uploadresult etc. The main variables which does the trick are — RequireUploadifySessionSync,SecurityToken,SessionId
[sourcecode language=”html”]
<script type="text/javascript">
var UploadifyAuthCookie = ‘<% = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>’;
var UploadifySessionId = ‘<%= Session.SessionID %>’;
$("#file_upload").uploadify({
‘buttonImage’: ‘/MultipleUploads/_scripts/browse-btn.jpg’,
‘scriptData’: { RequireUploadifySessionSync: true, SecurityToken: UploadifyAuthCookie, SessionId: UploadifySessionId },
‘formData’: { ‘KeyA’: ‘AValue’, ‘KeyB’: 1, RequireUploadifySessionSync: true, SecurityToken: UploadifyAuthCookie, SessionId: UploadifySessionId, UserName: UploadifyUserName }, // If some static data
‘auto’: false,
‘multi’: ‘true’,
‘swf’: ‘_scripts/uploadify.swf’,
‘uploader’: ‘<%= ResolveUrl("FileUploads.aspx") %>’,
‘onUploadStart’: function (file) {
// for all dynamic data
var objCheckUnPack = document.getElementById("chkUnpack");
var objCheckOverwrite = document.getElementById("chkOverwrite");
//                    alert(objCheckUnPack.checked);
//                    alert(objCheckOverwrite.checked);
$("#file_upload").uploadify("settings", "formData", { ‘IsUnPack’: objCheckUnPack.checked, ‘IsOverwrite’: objCheckOverwrite.checked });
//http://stackoverflow.com/questions/10781368/uploadify-dynamic-formdata-does-not-change
},
‘onQueueComplete’: function (queueData) {
alert(queueData.uploadsSuccessful + ‘ files were successfully uploaded. And there were few errors during upload for this number of files : ‘ + queueData.uploadsErrored);
window.open(‘<%= ResolveUrl("FileUploadResultPage.aspx") %>’, ‘Test’, ‘width=300,height=300’);
}
});
});
[/sourcecode]
2. Now, in Global.asax we have to handle this variables:
[sourcecode language=”csharp”]
protected void Application_BeginRequest(Object sender, EventArgs e)
{
// This check will ensure that we need to sync session only during uploadify upload!
if (HttpContext.Current.Request["RequireUploadifySessionSync"] != null)
UploadifySessionSync();
}
/// <summary>
/// Uploadify uses a Flash object to upload files. This method retrieves and hydrates Auth and Session objects when the Uploadify Flash is calling.
/// </summary>
/// <remarks>
///     Kudos: http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx
///     More kudos: http://stackoverflow.com/questions/1729179/uploadify-session-and-authentication-with-asp-net-mvc
/// </remarks>
protected void UploadifySessionSync()
{
try
{
string session_param_name = "SessionId";
string session_cookie_name = "ASP.NET_SessionId";
if (HttpContext.Current.Request[session_param_name] != null)
UploadifyUpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
}
catch { }
try
{
string auth_param_name = "SecurityToken";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
if (HttpContext.Current.Request[auth_param_name] != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(HttpContext.Current.Request.Form[auth_param_name]);
if (ticket != null)
{
FormsIdentity identity = new FormsIdentity(ticket);
// This helped us to restore user details
string[] roles = System.Web.Security.Roles.GetRolesForUser(identity.Name);
System.Security.Principal.GenericPrincipal principal = new System.Security.Principal.GenericPrincipal(identity, roles);
HttpContext.Current.User = principal;
}
UploadifyUpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
}
}
catch { }
}
private void UploadifyUpdateCookie(string cookie_name, string cookie_value)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
if (cookie == null)
cookie = new HttpCookie(cookie_name);
cookie.Value = cookie_value;
HttpContext.Current.Request.Cookies.Set(cookie);
}
[/sourcecode]
Happy Uploading via Uploadify! 🙂

TreeView.FindNode with PopulateOnDemand feature

Challenge:

If you are using Tree View with PopulateOnDemand feature – for those who are new to PopulateOnDemand feature – It Indicates whether the node is populated dynamically for example if you have tree structure as below:

imageNow, Normally you can bind above tree view on page load directly with all child nodes. But if you have huge data then it will affect performance. So, to avoid performance issue we use PopulateOnDemand feature as name suggests Nodes will be populated on demand only[on click of + sign]. Now our new data binding code will load all root nodes only and set it’s PopulateOnDemand property to true as shown here:

Markup code

<asp:TreeView ID="LinksTreeView" Font-Names="Arial" ForeColor="Blue" OnTreeNodePopulate="PopulateNode"
           SelectedNodeStyle-Font-Bold="true" SelectedNodeStyle-ForeColor="Chocolate" runat="server">
       </asp:TreeView>

Code-Behind

protected void Page_Load(object sender, EventArgs e)
    {  
        if (!IsPostBack)
        {
            // bind first level tree
            TreeNode treeNode1 = GetTreeNode("1");
            treeNode1.Expanded = false;
            LinksTreeView.Nodes.Add(treeNode1);

            TreeNode treeNode2 = GetTreeNode("2");
            treeNode2.Expanded = false;
            LinksTreeView.Nodes.Add(treeNode2);

            TreeNode treeNode3 = GetTreeNode("3");
            treeNode2.Expanded = false;
            LinksTreeView.Nodes.Add(treeNode3);

            // collapse all nodes and show root nodes only
            LinksTreeView.CollapseAll();
        }
    }

private static TreeNode GetTreeNode(string nodeTextValue)
    {
        TreeNode treeNode = new TreeNode(nodeTextValue, nodeTextValue);
        treeNode.SelectAction = TreeNodeSelectAction.SelectExpand;
        treeNode.PopulateOnDemand = true;
        return treeNode;

    }

protected void PopulateNode(Object sender, TreeNodeEventArgs e)
    {

        // Call the appropriate method to populate a node at a particular level.
        switch (e.Node.Text)
        {
            case "1":
                // Populate the first-level nodes.
                e.Node.ChildNodes.Add(GetTreeNode("1.1"));
                e.Node.ChildNodes.Add(GetTreeNode("1.2"));
                e.Node.ChildNodes.Add(GetTreeNode("1.3"));
                break;
            case "2":
                // Populate the second-level nodes.               
                e.Node.ChildNodes.Add(GetTreeNode("2.1"));
                e.Node.ChildNodes.Add(GetTreeNode("2.2"));
                e.Node.ChildNodes.Add(GetTreeNode("2.3"));
                break;
            case "3":
                // Populate the third-level nodes.               
                e.Node.ChildNodes.Add(GetTreeNode("3.1"));
                e.Node.ChildNodes.Add(GetTreeNode("3.2"));
                e.Node.ChildNodes.Add(GetTreeNode("3.3"));
                break;
            case "1.1":
                // Populate the first-level nodes.
                e.Node.ChildNodes.Add(GetTreeNode("1.1.1"));
                e.Node.ChildNodes.Add(GetTreeNode("1.1.2"));
                e.Node.ChildNodes.Add(GetTreeNode("1.1.3"));
                break;
            case "1.1.1":
                // Populate the first-level nodes.
                e.Node.ChildNodes.Add(GetTreeNode("1.1.1.1"));
                e.Node.ChildNodes.Add(GetTreeNode("1.1.1.2"));
                e.Node.ChildNodes.Add(GetTreeNode("1.1.1.3"));
      
          break;
            default:
                // Do nothing.
                break;
        }
    }

Great! Now we are ready just run your application and see the power of PopulateOnDemand feature. Whenever you expand any node[by clicking on plus sign] it will call PopulateNode Method because in tree view’s markup we have binded it.

Now, the main problem is here. Suppose you have a requirement in which you have to find 1.1.1.1 Node –which is at path 1/1.1/1.1.1/1.1.1.1. You will shout and say use TreeView’s FindNode method and provide path like this :

LinksTreeView.FindNode(“1/1.1/1.1.1/1.1.1.1”);

can you pls give a try and check does it works? it won’t because I’ve already tried 🙂 let me tell you why – Because 1.1.1.1 node is not loaded yet and it’s parent node 1.1.1 is also not loaded yet and so on still 1.1. Just 1 has been loaded. So, let’s see how we can solve this challenge:

Solution:

After goggling a bit and braining a lot i found the following way:

Main aim is to load 1.1.1.1 but it’s the last node and to load it all it’s parent’s should be first loaded. Here’s the simple way of doing it:

LinksTreeView.FindNode(“1”).Expand(); // it will find node and call expand method so it will load 1.1 which is first child of 1

LinksTreeView.FindNode(“1/1.1”).Expand();  //loads 1.1.1

LinksTreeView.FindNode(“1/1.1/1.1.1”).Expand(); //loads 1.1.1.1

LinksTreeView.FindNode(“1/1.1/1.1.1/1.1.1.1”).Expand(); //Cheers we reached there!

Now, above code is bit hard-coded and i am against of hard-coding so wrote one generic method which works for any level of node finding[txtPath is one textbox which provides path to find]

protected void btnSelect_Click(object sender, EventArgs e)
   {  
       //It will not work because as it is populateondemand
       //this call will never find node because of populateondemand
       TreeNode foundNode = LinksTreeView.FindNode(txtPath.Text);
       if (foundNode == null)
       {
           // Now i am doing different way
           string selecteValuePath = txtPath.Text;
           string[] selectedValues = selecteValuePath.Split(LinksTreeView.PathSeparator);

           string findValueQuey = string.Empty;
           for (int counter = 0; counter < selectedValues.Length; counter++)
           {
               string fValuePath = string.Empty; ;
               if (counter == 0)
               {
                   // store 1
                   fValuePath = selectedValues[counter];
               }
               else if (counter < selectedValues.Length)
               {
                   // now path is 1/1.1
                   fValuePath = findValueQuey.ToString()
                       + LinksTreeView.PathSeparator
                       + selectedValues[counter];
               }

               //1/1.1/1.1.1/1.1.1.1
               foundNode = LinksTreeView.FindNode(fValuePath);

               if (foundNode != null)
               {
                   foundNode.Expand(); //loads child node
                   foundNode.Select();
                   // stored 1
                   // stored 1/1.1
                   findValueQuey = fValuePath;
               }               
           }
       }
       else
       {
           Response.Write("Node found : " + foundNode.Value);
       }
   }

Happy Node Finding!

Showing Default Date and Visible Date with Calendar control

Challenge:

if you are using Calendar control to show Birthday of your friend. So, when you run the application it will show whose b’day is coming in this month or next month or next month …. So, you can be ready for a treat 🙂 . The Challenge here is how to select that particular date and how to make it visible while user runs the application?

Solution:

You can set SelectedDate of Calendar Control to show date selected like this:
DateTime dtBirthday = getUpcomingBirthday(); //assume this method returns upcoming b’day in DateTime
calBirthday.SelectedDate = dtBirthday.Date; //use Date here else it won’t work
You can set VisibleDate of Calendar Control to show that date:
calBirthday.VisibleDate= dtBirthday.Date; //use Date here else it won’t work
Here DateTime.Date part it too important. Else it won’t work. Do you know why? i know but it’s homework for you guys 🙂
Cheers

using Table control

Challenge:

How I generate <tbody> tag using Table, TableRow, etc … controls ?

I want to generate table o/p like this:

<table border="1">
  <thead>
    <tr>
      <th>Month</th>
      <th>Savings</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>January</td>
      <td>$100</td>
    </tr>
    <tr>
      <td>February</td>
      <td>$80</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Sum</td>
      <td>$180</td>
    </tr>
  </tfoot>
</table>

Src : http://www.w3schools.com/TAGS/tag_tbody.asp

I want to create table like this from my code

behind using .net f/w classes.

Solution:

TableRow.TableSection is the solution for it:

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.tablerow.tablesection.aspx

for whatever row you create just provide it’s TableSetion property to appropriate section e.g Body,head etc.

Hope this helps

Happy Programming!!