Friday, December 9, 2011

Disabling ViewState not working in ASP.net


I have conducted many interviews, talked to the seasoned and experience .net developers and guess what 99% of them were confident enough to tell me that if you disable the view state of a asp.net control your data for that control won't be post back to server. If you are one of that 99%, you need to read that it is not true 'completely'.
ASP.net is build on the top of HTTP so it inherits some of the property of HTTP protocol. One of that property is HTTP is stateless so is ASP.net states are maintained in different ways in ASP.net. One of them is view state.
Before I prove my point, I want you to do this.
  1. Create a brand new ASP.NET Web Site project.
  2. In Default.aspx, drop one asp.net text box & one asp.net button control on this page. 
  3. Disable the view state of whole page by placing EnableViewState="false" in the page directives.
  4. Disable the view state of Form by enableviewstate="false" property.
  5. Disable the view state of text box by enableviewstate="false" property.
  6. Go to Page_Load function of Default.aspx and write the following code.

    protected void Page_Load(object sender, EventArgs e)
        {       
    if (IsPostBack)
            {
    
    



       System.Web.HttpContext.Current.Response.Write(@"<script javascript""="" language=""> alert('" + TextBox1.Text + "') </script>");

    
    
    

        }

  7.  Run the application and type something in the text box and press enter or click the button to post it back to the server.I am confident enough that your data will be displayed in alert box though you have disabled the viewstate of whole page, form and textbox control.
I understand that you must be thinking this is bug or something but it is not. I will explain it in the bottom section but for right now I want you to drop a asp.net label control and disable its view state by enableviewstate="false.
Now add the following lines in your Page_Load event and re run the applicaiton.



if (IsPostBack)
        {  
System.Web.HttpContext.Current.Response.Write(@"<SCRIPT LANGUAGE=""JavaScript"">alert('" + Label1.Text + "')</SCRIPT>");
            Label1.Text = "My label";
        }

Click on Button to post back the page. You will see an alert box with the lable's text property as "Label". In the above code, we have actually changed the label's text property to "My Label" after the first post back. You see that now label's text property is "My Label" displayed on the page. Hit the button one more time. This time you will see that since the view state of label's control is disabled, asp.net set the default value of label's control "Label" instead of "My Label". Therefore when the 2nd post back occur we see "Label" on alert box .

Go ahead and turn on the view state of the label, first make sure the page's & Form's view state property is set to true too otherwise childlren control's view state property won't work.
Rerun the application and click on the button for first time to let the label change its text to "My Label".This time the alert box displayed "Label",which is expected. Click on button 2nd time. Aha! did you see that now asp.net retains the value of this label's text property and showed us "My Label"?
Do the same thing for textbox. Enable the viewstate property of textbox and try it. You won't find a difference. Confused?

Well this incident was reported back to Microsoft years ago and here is the justification of what Microsoft says about it. Please go ahead and read it thoroughly. Yes, there are 3 server controls i.e textbox, checkbox and radio button who retains their value from forms collection even if you disable the view state of them.But there are certain attributes of these control which can't function properly without Viewstate.

The articles says that this incident applies to .net 1.0 and 1.1. But for sure this works till 4.0. They just didn't get time to update it.


Wednesday, November 16, 2011

How to access a private member outside a class


There is a misconception between C# developers that member access specifier like Private restricts the accessibility outside of that class where it is declared.
Today I am going to show you that it is possible via reflection to not only access those private members but you can change and manipulate them as you want.
Here is the link from Microsoft that tells us something about member access specifiers.
Worth noting the definition of Private access specifier

private
The type or member can be accessed only by code in the same class or struct

Alright, Lets jump on to the code to demonstrate how to access private member.
Lets create a Console Application and name it as ReflecitonDemo. Put the solution name AccessingPrivate.
Right click on ReflectionDemo project to add a class. Let's name it as SampleClass.
Type or paste the following snippet into SampleClass

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ReflectionDemo
{
     class SampleClass
    {
        private string privateVariable = "Hey! I am private string variable of SampleClass";
        private String PrivateProperty
        {
            get
            {
                return privateVariable;
            }
            set
            {
                privateVariable = value;
            }
        }
        private string PrivateMethod()
        {
            return "Hey! I am private Method of SampleClass.";
        }
     
    }
}



As you can see this class has 3 private members. A variable, property that uses that string variable and a private method that returns a string.
Double click on your Program.cs file and write/paste the following code in it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

using Payroll;

namespace ReflectionDemo
{
    class Program
    {
        static string decorator="**************************************************************";
        static void ShowMemembers(object type)
        {
            Console.WriteLine("Showing all the members of " +type.GetType().Name+" class");
            foreach (MemberInfo m in type.GetType().GetMembers(BindingFlags.Instance | BindingFlags.NonPublic|BindingFlags.DeclaredOnly))
            {
                Console.WriteLine(m.Name);
            }
            Console.WriteLine(decorator);
            Console.ReadLine();
        }
        static void InvokePrivateMethod(object type,string methodName)
        {
            //Let's inovke the private method of this class
             Console.WriteLine(decorator);
            
            Console.WriteLine( type.GetType().GetMethod(methodName,BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.InvokeMethod|BindingFlags.DeclaredOnly).Invoke(type, null));
            Console.WriteLine(decorator);
            Console.ReadLine();
        }
        private static void ChangePrivateField(Object type, string fieldName,object newValue)
        {
            FieldInfo field = type.GetType().GetField(fieldName,BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.DeclaredOnly);
            Console.WriteLine("Old value of private field: '{0}' of Class {1} is :\r\n  ",fieldName,type.GetType().Name);
            Console.WriteLine(decorator);
            Console.WriteLine(field.GetValue(type));
            Console.WriteLine(decorator);
            
                    
            field.SetValue(type, newValue);
            //Lets see what we did with poor private variable.
            Console.WriteLine("New value of private field: '{0}' of Class {1} is :\r\n  ", fieldName, type.GetType().Name);
            Console.WriteLine(decorator);
            Console.WriteLine(type.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.DeclaredOnly).GetValue(type));
            Console.WriteLine(decorator);
         
            Console.ReadLine();
       
        }
        static void Main(string[] args)
        {
            //http://msdn.microsoft.com/en-us/library/ms173121.aspx

            SampleClass sc = new SampleClass();

            ShowMemembers(sc);
            Console.WriteLine("Calling Private method of SampleClass");
            InvokePrivateMethod(sc, "PrivateMethod");
            Console.WriteLine("Calling Private variable of SampleClass");
            ChangePrivateField(sc, "privateVariable","Your wish my command");

            Console.Clear();
            List<string> list = new List<string>();
            list.Add("Talal");
            list.Add("Khan");
            Console.WriteLine(decorator);
            Console.WriteLine("List count is: {0}", list.Count);
            Console.WriteLine(decorator);
            Console.ReadLine();
            Console.Clear();
            ShowMemembers(list);

            ChangePrivateField(list, "_size",10);


            Console.WriteLine(decorator);
            Console.WriteLine("List count is: {0}", list.Count);
            Console.WriteLine(decorator);


            Console.Clear();

            Employee John = new Employee();
            John.EmployeeId = 1001;
            John.FirstName = "John";
            John.LastName = "Teddy";
            John.Address = "122 Awesome drive, Richmond, VA, 23238";
            John.GetEmployeeSalarybyID(John.EmployeeId);
            Console.WriteLine(John.Salary.ToString());


            Employee Mary = new Employee();
            Mary.EmployeeId = 1002;
            John.FirstName = "Mary";
            John.LastName = "Jones";
            John.Address = "1345 Noway drive, Richmond, VA, 23238";
            Mary.GetEmployeeSalarybyID(Mary.EmployeeId);
            Console.WriteLine(Mary.Salary.ToString());

           
            Employee Talal = new Employee();
            Talal.EmployeeId = 1003;
            John.FirstName = "Talal";
            John.LastName = "Khan";
            John.Address = "900 pump road, Richmond, VA, 23238";
            Talal.GetEmployeeSalarybyID(Talal.EmployeeId);
            Console.WriteLine(Talal.Salary.ToString());

            ChangePrivateField(Talal, "_Salary", 99999.99);
            Console.WriteLine(Talal.Salary.ToString());
            Console.ReadLine();
        }
   }
}

The point of interest in this code snippets are three static methods named
  1.  ShowMemembers
  2.  InvokePrivateMethod
  3.  ChangePrivateField
The names are pretty self explanatory.
Let's jump on these method and see what they does.

ShowMembers Function; This method uses reflection to show only private members of a type that is passed as its parameter.In our above code, we are passing SampleClass type to this method as parameter.
The output if you run the project will show you all the private members defined only in this type, no inherited or child's type members will be shown.
Let's dig into this function line by line.


Console.WriteLine("Showing all the members of " +type.GetType().Name+" class");


This line is self explanatory. This line will display a string on console that says "Showing all the members of SampleClass class".



foreach (MemberInfo m in type.GetType().GetMembers(BindingFlags.Instance | BindingFlags.NonPublic|BindingFlags.DeclaredOnly))
            {
                Console.WriteLine(m.Name);
            }


Ah! The following code snippet is what you need to access the private members of a type. As you can see in this code, reflection is being used to get the type of the type that has been passed as a parameter and then once we found that type, we use a built in function called GetMemebers() which is a overloaded method to return an array of string. This method takes BindingFlags enum type as a parameter. Now that our motive is to get all the private member of this type only, we have to use bit-wise shift operator for BindingFlags.
That's why I have used, Instance, NonPublic(for priavate Members) and DeclaredOnly(only from this type) flag. You can see the details of each flag on MSDN site here.


Guess what, this code will spits out the following output on console.




If you look closely in Sample class we have defined only 3 private members. Private variable,  private property and private method. but the output shows 2 more properties; get_PrivateProperty & set_PrivateProperty. Remember, in .Net a property is nothing but combination of merely a getter and setter function.
Alright, now that we have seen all the private members of this class let's jump to next function called InvokePrivateMethod.


InvokePrivateMethod Function:
This method also uses reflection to invoke a private method. Once you have identified the name of the private function as in our case it is "PrivateMethod", We pass this alone with the object to invoke it.
Let's dig into this code base.



Console.WriteLine( type.GetType().GetMethod(methodName,BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.InvokeMethod|BindingFlags.DeclaredOnly).Invoke(type, null));



As you can see the above line uses a built in overloaded function GetMethod which uses two parameters, name of parameter and binding flag to reach out that function.
In addition to the binding flags that we discussed previous we have used another binding flag called BindingFlags.InvokeMethod which is used to tell the compiler that this method is to be invoked.
Once we get the required method from GetMethod(), we use Invoke function of MethodBase class to invoke this method and pass the object(in this case SampleClass).
The following is the output on the console.





Did you see, we called a private method named PrivateMethod of class SampleClass. Impressive?



ChangePrivateField Function:
As it name indicates this generic method I have created is used to change the value of any private field in any class. You can see the default value of string (privateVariable) in SampleClass is "Hey! I am private string variable of SampleClass". By calling this method, I am able to change that string to "Your wish  is my command".
Let's see how.


FieldInfo field = type.GetType().GetField(fieldName,BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.DeclaredOnly);




This code is being used to get the private field of the SampleClass and store the reference in FieldInfo type. Now that we have got the private field, we can get its current value.


field.GetValue(type));


Now, I can see what you are thinking. If you can get the value, can we set the value? Sure, why not.
There is method called SetValue that you can use to change its value.



field.SetValue(type, newValue);



As you can see, this method expect two parameter, the object to which this field belong and new value.
Here is the output of this method on the console.






Now that we have learned how to manipulate these private field. Do you want to try this technique to some of the classes shipped with .Net such as List class?

Alright then, lets declare a list of string and add 2 string to that list as show below.


Console.Clear();
List<string> list = new List<string>();
list.Add("Talal");
list.Add("Khan");
Console.WriteLine(decorator);
Console.WriteLine("List count is: {0}", list.Count);
Console.WriteLine(decorator);




The output of this code should be 2. No tricks in there.
Now lets call ShowMembers function and pass this list object to that method.
You will get a list of all the private members as expected. Now that I pick _size variable from those private members list. 
This is private variable of type int which Count read-only property uses to display you the count. I want to mess with it. I want to change the count from 2 to 200. Can I do that? Well before reading this article you probably would say No. But now your answer would be yes.
Call ChangePrivateField with list object, _size as fieldName, and 200 as new value.




 ChangePrivateField(list, "_size",200);


Now output the count again.


Console.WriteLine(decorator);
Console.WriteLine("List count is: {0}", list.Count);
Console.WriteLine(decorator);



What did you see? 200 or 2 :)
Okay fair enough, you can now play with any type that has reflection permission on it or the type's code is not obfuscated. 
Cheers.

Source Code