Tuesday, June 23, 2009

Reading from a configuration file in .NET.

Recently I was working on a web application which had an exe added as a reference to the project. The exe had its own App.Config file where some setting related to the application was saved and these were read using the code below. Pretty straight forward code.

private static string userName = ConfigurationSettings.AppSettings["UserName"].ToString();
private static string userEmail = ConfigurationSettings.AppSettings["UserEmail"].ToString();

In the above code we are trying to retrieve value from the AppSettings section of the App.Config file of the application using the ConfigurationSettings class’ AppSettings property which is a namevalue collection object. The above approach is a deprecated method. Instead of the above approach, one can make use of the below code to retrieve the appsettings values.

private static string userName = ConfigurationManager.AppSettings["UserName"].ToString();
private static string userEmail = ConfigurationManager.AppSettings["UserEmail"].ToString();

ConfigurationSettings API has become obsolete and has been replaced with the ConfigurationManager class to read the configuration  setting of an applicatioin. To read the application settings or AppSettings of an application one can make use of ConfigurationManager.AppSettings. But my problem was not related to the API becoming obsolete. The system was throwing error when the system was trying to read the configuration. The errors are pasted below.

The parameter 'exePath' is invalid.
Parameter name: exePath

An error occurred loading a configuration file: The parameter 'exePath' is invalid.
Parameter name: exePath

Object reference not set to an instance of an object.

The reason why these errors were thrown is that while we were trying to read the keys from the configuration file the key were actually not present  in the “AppSettings” section.

As I said earlier the exe file was added as a reference in an ASP.NET web application and due to some reason when the exe code was accessed through the ASP.NET web application it was throwing error. The same exe application when executed independently was running without any exceptions.

On debugging it was found that, as the request was coming from the ASP.NET web application to the exe file the ConfigurationManager’ AppSettings property had values from the appSettings section of web.config file of the web application. But I wanted the appSettings values of the App.Config file of the exe application. The only solution to my problem was to read from the app.config file of the exe file. Below is the code to read from the configuration file.

string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, “Bin”);
/*If checking to check whether the bin folder exists. As this is a console application the exe can be copied to any place and can be executed. If that is the case there will be no bin folder. */
if (!Directory.Exists(filePath))
{
    filePath = AppDomain.CurrentDomain.BaseDirectory;
}
/*As the request for this class can come from both exe and website we need to combine the paths. We are first retrieving the path using the AppDomain' BaseDirectory propety and then retrieving the exe name alone. Finally passing the combined file path to ConfigurationManager class. */
filePath = Path.Combine(filePath, Path.GetFileName(System.Reflection.Assembly.
GetExecutingAssembly().Location));
System.Configuration.Configuration theConfig = ConfigurationManager.
OpenExeConfiguration(filePath);

KeyValueConfigurationCollection configuration = theConfig.AppSettings.Settings;
userName = configuration["UserName"] == null ? string.Empty :
configuration["UserName"].Value;
userEmail = configuration["UserEmail"] == null ? string.Empty :
configuration["UserEmail"].Value;

In the above code I am using AppDomain class to retrieve the directory from where the application is executing itself. This approach was taken because the exe will run on its own or can be copied and pasted anywhere and it can run from there or as in my case the request can come from an ASP.NET application. If the exe is added as a reference in an ASP.NET web application, the exe will be copied to the bin folder of the ASP.NET application. So you can see there is a checking to see if there is a “Bin” folder, if there is one the app.config settings will be read from there else it will read from the base directory.

Once the file path along with the exe file name is properly formed we are using ConfigurationManager’ OpenExeConfiguration method to open the configuration file of the exe file. One thing to note here is that we are using “GetExecutingAssembly().Location” property and retrieving the file name and passing the application name along with the extension (.exe) to the OpenExeConfiguraiton method. There is no need to specify “app.config” file name. The reason is whenever an exe is successfully compiled it will create a config file with the same name with a .config extension. For e.g. if you have an exe named “one.exe”, if it is successfully compiled it will create a config file with “one.exe.config” as the name.

Once the config file is successfully opened using “OpenExeConfiguration” method it returns a Configuration object. After successfully retrieving the configuration object, in the next line we are getting the application’ settings using the “AppSettings.Settings” property. The “Settings” property returns a “KeyValueConfigurationCollection” object. Using KeyValueConfigurationCollection object one can read the values of the configuration file. In the above code we are using “configuration["UserName"]” to read the value stored against the “UserName” key. Here the “UserName” is the key. So that’ about reading configuration settings from a configuration file of an application.

Try to know more.

Sandeep

Friday, June 5, 2009

Difference between $get and $find

In my previous blogs I have made use of $get and $find javascript methods. These are new shortcut methods available in ASP.NET AJAX. To use these methods one has include ScriptManager in an aspx page. What are these two methods all about? Lets see one by one.

$get

$get is the shortcut method for document.getElementById. If you put a break point in the $get function and step into the function you can see the following code.

var $get = Sys.UI.DomElement.getElementById = function Sys$UI$DomElement$getElementById(id, element) { 
    var e = Function._validateParams(arguments, [
        {name: "id", type: String},
        {name: "element", mayBeNull: true, domElement: true, optional: true}
    ]);
    if (e) throw e;
    if (!element) return document.getElementById(id);
    if (element.getElementById) return element.getElementById(id);
    var nodeQueue = [];
    var childNodes = element.childNodes;
    for (var i = 0; i < childNodes.length; i++) {
        var node = childNodes[i];
        if (node.nodeType == 1) {
            nodeQueue[nodeQueue.length] = node;
        }
    }
    while (nodeQueue.length) {
        node = nodeQueue.shift();
        if (node.id == id) {
            return node;
        }
        childNodes = node.childNodes;
        for (i = 0; i < childNodes.length; i++) {
            node = childNodes[i];
            if (node.nodeType == 1) {
                nodeQueue[nodeQueue.length] = node;
            }
        }
    }
    return null;
}

From the above code one can infer that the signature of the shortcut method is something like this.

$get(id, element)

The function argument “id” takes a string value where one can pass the id of the element to be retrieved. “element” is an optional parameter, if passed the code will try to find a control inside the element if it supports getElementById else it will loop through all the child nodes and match the id of the child node with the id passed as the function argument. Below sample code shows the usage of the $get.

//Getting the ASP.NET server control' id using the ClientID.
var txtCntl = $get('<% =txtChange.ClientID%>');
//Getting a control which is not a server control
var divCntl = $get('contentDiv');
//Passing the id of the control as well the control in which the controls needs to be searched.
var dropDownCntl = $get('<% =ddCountries.ClientID %>', divCntl);

--Html tag for the above controls is pasted below--
<form id="form1" runat="server">
    <div id="contentDiv">
        <asp:DropDownList ID="ddCountries" runat="server">
        </asp:DropDownList>
        <asp:TextBox ID="txtChange" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="Button" />       
    </div>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
</form>

In the above code we have seen the different ways of retrieving a control using the $get function. If you see the javascript code pasted above one can see in the first line we are trying to retrieve a ASP.NET server control using inline server code where we are using ClientID property to retrieve the system generated ID for the server control. In the second line we are using the id of the Div tag to retrieve the div control. Finally in the third line we are making use of ClientID and then passing the div control retrieved in the second line as the second argument to $get function. What happens in the third approach is that the $get function tries to find the control inside the div tag. So that’ about the $get function.

$find

$find is the shortcut method for “Sys.Application.findComponent(id, parent)”. The function takes id as a string parameter and also the control in which the component needs to be searched. The second parameter is optional. If provided it will look for the component in the component or element passed as an argument. The signature of the method is as follows.

$find(id, parent)

The method looks for components registered with the addComponent javascript method. If you put a debug point and step into the function you can see the below code.

function Sys$_Application$findComponent(id, parent) {
    var e = Function._validateParams(arguments, [
        {name: "id", type: String},
        {name: "parent", mayBeNull: true, optional: true}
    ]);
    if (e) throw e;
    // Need to reference the application singleton directly beause the $find alias
    // points to the instance function without context. The 'this' pointer won't work here.
    return (parent ?
        ((Sys.IContainer.isInstanceOfType(parent)) ?
            parent.findComponent(id) :
            parent[id] || null) :
        Sys.Application._components[id] || null);
}

From the above code you can see that the code first checks whether the parent element is of type IContainer if it is then it tries to find the component within the parent component else it returns the component from the _components array in the Sys.Application object.

When to use $get and $find?

$get javascript shortcut method can be used instead of document.getElementById whereas $find can be used to find extender controls. If you use $get to retrieve extender controls like ValidatorCalloutExtender, AutoCompleteExtender etc it will return null.

So that's the difference between $get and $find.

Monday, June 1, 2009

Anonymous Types – Features of C# 3.0 (Part – 5)

In my previous blogs we have discussed the various new features of C# 3.0. These are listed below.

In this blog we will see what are Anonymous types?

Anonymous Types 

As the name suggests anonymous types are types which don’t have any concrete type. This doesn’t mean that anonymous types are not strongly typed. Anonymous types help you in creating real time objects without the hassle of creating a class and declaring an object for the same. Normally in .NET or any OOPS programming language we create object by first creating a class for the object and then instantiate an object for the class using the new keyword. With anonymous types one need not do all these, the developer can use the “new” keyword along with the “var” keyword and Object Initializer to create an anonymous object. The sample code for creating anonymous object is shown below.

var anonymousObj = new { FirstName = "Sandeep", LastName = "P.R" };

In the above code you can see I am creating an Anonymous object with two properties “FirstName” and “LastName” by making use of Object Initializer feature. One can access the properties defined in the Anonymous type using the Anonymous type’ variable name. One will get the intellisense feature as well with anonymous types. The below screenshot shows the intellisense displaying the properties defined above.

image

If you closely examine the intellisense you can see some methods. These methods are the ones available in the System.Object class of .NET. The reason why these methods are available is that anonymous types implicitly inherit from .NET’ System.Object class. Just to prove that Anonymous types implicitly inherit from System.Object I have disassembled the exe using .NET Reflecter. The screenshot pasted below proves just that.

image

As said previously one need not create class/type for instantiating an anonymous type but behind the scene the compiler does the extra work of creating the class/type and giving it a name. In the above screenshot one can see compiler generated class name highlighted in blue. The auto generated name cannot be accessed in your code and that is the reason the “var” keyword is used whenever anonymous types are instantiated. Anonymous types are reference types (class) and are not different from other user defined types. In user defined types the type is created by the user whereas in the case of anonymous type the compiler does the extra work of creating the type. The code pasted below is the compiler generated code for the anonymous type that we created in the above code.

[CompilerGenerated, DebuggerDisplay(@"\{ FirstName = {FirstName}, LastName = {LastName} }", Type="<Anonymous Type>")]
internal sealed class <>f__AnonymousType0<<FirstName>j__TPar, <LastName>j__TPar>
{
    // Fields
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly <FirstName>j__TPar <FirstName>i__Field;
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly <LastName>j__TPar <LastName>i__Field;

    // Methods
    [DebuggerHidden]
    public <>f__AnonymousType0(<FirstName>j__TPar FirstName, <LastName>j__TPar LastName);
    [DebuggerHidden]
    public override bool Equals(object value);
    [DebuggerHidden]
    public override int GetHashCode();
    [DebuggerHidden]
    public override string ToString();

    // Properties
    public <FirstName>j__TPar FirstName { get; }
    public <LastName>j__TPar LastName { get; }
}

In the above disassembled code, the first line says “CompilerGenerated”, this distinguishes user defined code from compiler generated code. Also notice the auto generated class is declared internal and sealed. The fields which hold the values of the properties are defined as read only.

Anonymous type’ properties are read only and they cannot be set at any given point. If you write a code to set the properties of anonymous types the following error will be thrown.

var anonymousObj = new { FirstName = "Sandeep", LastName = "P.R" };
anonymousObj.FirstName = "Sad";// Error prone code.

Compile time error which is thrown when you try to assign a value to a property of an Anonymous type is pasted below.

Property or indexer 'AnonymousType#1.FirstName' cannot be assigned to -- it is read only

Anonymous types can have only read only properties and they cannot have any method definition or events but they inherit the default methods of the Object class. If you use the Equals methods of an anonymous type the system loops through all the properties and returns true if all the properties are same. Even GetHashCode method works based on the equality of properties. So the implementation of Equals and GetHashCode changes in the case of Anonymous Types. The output of ToString and GetType methods which are inherited from the System.Object class is pasted below.

var anonymousObj = new { FirstName = "Sandeep", LastName = "P.R" };
Console.WriteLine(anonymousObj.ToString());
Console.WriteLine(anonymousObj.GetType().ToString());

//Output of ToString
{ FirstName = Sandeep, LastName = P.R }
//Output of GetType().ToString()
<>f__AnonymousType1`2[System.String,System.String]

The scope of anonymous types is limited to only method level. If one wants to transfer anonymous types from one method to another method then one has to cast the anonymous type to object and then pass it to other functions. In the function where you are receiving the anonymous object as an Object type there is no way to directly retrieve the property values. You cannot make use of the property names and retrieve the values. If you are passing anonymous types to another function then the below code is the only way to retrieve the property values.

//Method where anonymous types are declared and passed to another method.
private void MakingUseOfAnonymousTypes()
{
    var anonymousObj = new { FirstName = "Sandeep", LastName = "P.R" };
    TakesAnonymousType(anonymousObj);
}

//Method which receives anonymous object as a method a parameter in the form object.
private void TakesAnonymousType(object obj)
{  
    //Getting the object' type.
    Type anonymous = obj.GetType();
    //Retrieving all the properties of the anonymous object.
    System.Reflection.PropertyInfo [] propertyInfo  = anonymous.GetProperties();
    //Looping through all the properties to retrieve the name and value.
    foreach (System.Reflection.PropertyInfo propInfo in propertyInfo)
    {
        Console.WriteLine(propInfo.Name + ": " + propInfo.GetValue(obj, null));
    }       
}

In the above code we are creating anonymous types in the first method (MakingUseOfAnonymousTypes) and passing the anonymous type to the next method. “TakesAnonymousType” method takes the anonymous type as a System.object type argument. Inside the method we are Making use of Reflection and getting the type of the object. After that we are retrieving the property collection of the object using the GetProperties method. Then looping through each property we are retrieving the property’ name and value.

Scenarios where anonymous types can be used

Anonymous types can be used where we want to use the scaled down version of a type with one or two properties. Suppose you have class called Employees with the following structure.

public class Employee
{
    public string FirstName
    { get; set; }
    public string LastName
    { get; set; }
    public int Age
    { get; set; }
    public DateTime DOB
    { get; set; }
    public string Department
    { get; set; }
    public string Address
    { get; set; }
    //Many more properties
}

Now there can be scenario in your business logic where you want to make use of only few of these properties, say FirstName and Department, instead of the long list of properties. In such scenarios you can create a scaled down version of the Employee class with only the required properties which you are going to use. Sample code is pasted below.

//Normal object with all the properties initialized
Employee emp = new Employee { FirstName = "Sandeep", LastName = "P.R", Address = "Blah blah", Age = 29, Department = "Software", DOB = new DateTime(1981, 06, 09) };
//Anonymous type
var scaledDownEmp = new { emp.FirstName, emp.Department };

In the above example you can see we are not specifying any names to the properties of the anonymous type instead we are directly using the property names of the Employee object. In such cases the compiler will assign the same name and type to the properties as that of the object from which it is being created, in this case Employee object. The compiler will automatically designate FirstName and Department as the property names and also assign the same data type to the anonymous object properties.

The best use of Anonymous types can be exemplified in the “Select” extension method of LINQ as shown below.

//Initializing the generic list collection object with two Employee object.
System.Collections.Generic.List<Employee> list = new System.Collections.Generic.List<Employee> { new Employee { FirstName = "Sandeep", LastName = "P.R", Address = "Blah blah", Age = 29, Department = "Software", DOB = new DateTime(1981, 06, 09) }, new Employee{FirstName = "Blah", LastName = "Blah blah", Address="blah blah", Age=19}};
//Another employee object being initialized.       
Employee emp = new Employee
{
      FirstName = "Employee 1",
      LastName = "Last Name",
      Address = "Blah blah",
      Age = 29,
      Department = "Software",
      DOB = new DateTime(1981, 06, 09)
};
//Another way of adding the emplyee object to the generic list collection.
list.Add(emp);
//Using LINQ extension methods and filtering out employees who are aged above 21
var empColl = from employee in list
      where employee.Age > 21
      select new { employee.FirstName, employee.Address };
//Looping through the anonymous object collection and printing the properties.
foreach (var em in empColl)
{
      Console.WriteLine(em.FirstName, em.Address);
}

From the above sample code we can see that we are creating a Generic List collection object and adding the employee object into the collection by making use of Object Initializer feature. Then we are filtering out the employees who are above 21 years of age from the collection using the LINQ’ Extension methods where, select and from. If you note in the select statement we are creating a new anonymous type with FirstName and Address as properties. empColl will hold a collection of anonymous types having FirstName and Address as properties. Immediatly below the LINQ expression we are looping through the anonymous collection and printing the properties.

So that’ about Anonymous types. Next we will see what are Lambda expressions, till then try to know more.

Sandeep