Tuesday, March 10, 2009

Calling an ASP.NET server side function from Javascript.

I know this blog discusses a very simple problem but this simple problem is being confused by many and there are lots of suggestion floating in the net for the solution, which needless to say is an exaggerated solution to a simple problem. This blog is purely meant to clear those myths, else I wouldn’t have blogged on such a simple issue in so length.

Many of us would have come across a scenario where we needed to call a server side asp.net function and retrieve a value, from within javascript/HTML. I have come across this scenario many a times. But, recently, while going through some forums I found many people giving suggestions to make use of ScriptManager, ASP.NET Ajax controls and other stuffs. ScripManager, ASP.NET Ajax controls etc are purely meant for enabling AJAX/Partial page loading concept. But the real problem here is to just call a server side function or access a server variable and use it in javascript or html.

I would say, without using all these high funda stuffs we can solve this problem pretty easily using inline server codes. Though I am not a very big fan of this type of coding but there is no escaping from it, I had to use inline server code in many places to embed some server side variable’ value or the return value of some function in javascript or html tags. The syntax used for doing so is <% Server side code goes here %>. One can write any server side code/logic either in C# or VB in between “<% %>”, but in this blog I will concentrate on retrieving output of a server side function as there are lots of myths associated with such a simple thing.

I am a big fan of localization and so I use resource files (wherever possible) or XML file to implement localization. In many situations while writing javascript I had to show the localized strings retrieved from the server. I have used the simple code shown below to retrieve data from the server.

<%@ Page Language="C#" MasterPageFile="~/MasterPages.Master" AutoEventWireup="true" CodeBehind="MyProjectHome.aspx.cs" Inherits="Home_TDI" Title="Home Page" %>
<%@ Import Namespace="Utilities"%>
<%@ Import Namespace="StaticContents" %>
<asp:Content ID="cnHomeTDI" ContentPlaceHolderID="mainContent" runat="server">

<script language="javascript" type="text/javascript">
var ajaxRequest;
// Script block to ping the server and get an AJAX request.
function sendAjaxRequest()
{
ajaxRequest = new XMLHttpRequest();
ajaxRequest.onreadystatechange = HandleResponse;
ajaxRequest.open("GET", "home.aspx?function=GetSomeCount", true);
ajaxRequest.send(null);
}

//Function which handles the AJAX response.!!! Sandeep
function HandleResponse()
{
if (ajaxRequest != undefined && ajaxRequest != null)
{
if (ajaxRequest.readyState == 1)
{
showText('<% =ResourceManagerUtility.GetString(Constants.PLEASE_WAIT) %>')
}
else if (ajaxRequest.readyState == 2)
{
showText('<% =ResourceManagerUtility.GetString(Constants.REQUEST_SENT) %>');
}
else if (ajaxRequest.readyState == 3)
{
showText('<% =ResourceManagerUtility.GetString(Constants.RECEIVING_REQUEST) %>');
}
else if (ajaxRequest.readyState == 4 && ajaxRequest.status == 200)
{
showText(ajaxRequest.responseText);
}
else if ((ajaxRequest.readyState == 4) && (ajaxRequest.status != 200))
{
alert('<% =ResourceManagerUtility.GetString(Constants.
SCREWED_UP_REQUEST) %>');
}
}
}

function showText(textToBeDisplayed)
{
var lblCntl = document.getElementById('<% = noRecordsFound.ClientID %>');
if (lblCntl != undefined && lblCntl != null)
{
lblCntl.innerHTML = textToBeDisplayed;
}
}
</script>
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tr>
<td></td>
</tr>
<tr>
<td>
<% =ResourceManagerUtility.GetString(Constants.WAITING) %>
</td>
</tr>
<tr>
<td>
<label id="noRecordsFound" runat="server" visible="false">
<% =ResourceManagerUtility.GetString(Constants.NO_RECORDS_FOUND) %>
</label>
</td>
</tr>
</table>
</asp:Content>

In the above code one can see that I am making use of the below line.

“<% =ResourceManagerUtility.GetString(Constants.[CONSTANT_NAME]) %>”

What the above code does is it invokes the static “GetString” method defined in “ResourceManagerUtility” class and retrieves the corresponding string attached to the constant without making use of the so called ScriptManager or ASP.NET AJAX or any other stuffs. The code for ResourceManagerUtility and Constants classes is shown below.

namespace TDI_Tool_Prototype.Utilities
{
public class ResourceManagerUtility
{
/// <summary>
/// Returns the localised strings from the default localised resource file.
/// </summary>
/// <param name="theKey">The key based on which the localised text has to be retrieved.</param>
/// <returns>Returns a string from the resource file.</returns>
public static string GetString(string thekey)
{
//Creating an instance of ResourceManager.
System.Resources.ResourceManager resourceManager = new
System.Resources.ResourceManager ("English", System.Reflection.Assembly.GetExecutingAssembly());
return resourceManager.GetString(thekey);
}
}
}

“GetString” method creates an instance of “ResourceManager” class and returns the value based on the key passed in the “theKey” argument of the function.

The “Constants” class structure is shown below.

public class Constants
{
public const string PENDING_INVESTMENT_REVIEW = "PENDING_REQUEST";
public const string NO_PENDING_INVESTMENT_REVIEW = "WAITING";
public const string SCREWED_UP_PENDING_REVIEW = "SCREWED_UP_REQUEST";
public const string PLEASE_WAIT = "PLEASE_WAIT";
public const string REQUEST_SENT_TO_SERVER = "REQUEST_SENT";
public const string RECEIVING_REQUEST_FROM_SERVER = "RECEIVING_REQUEST";
public const string NO_RECORDS_FOUND = "NO_RECORDS_FOUND";
public const string OPEN_CONNECTION = "OPEN_CONNECTION";
}

The above class holds only the constants. These constants are passed to the “GetString” method and based on these constants the localized strings are retrieved.

In many blogs I have seen people saying one can access only methods in a page’ code behind file, I would like to say it’s not true. One can very well access any method inside any class, namespace or dll by adding a reference to the namespace. In the above code I am accessing “ResourceManagerUtility” class from another namespace called “Utilities” by importing it in the aspx page using the below code.

<%@ Import Namespace="Utilities"%>

The above code imports the Utilities namespace. The code is similar to the below C# code.

using Utilities;

Once you have imported the namespace using the @Import attribute you can use a syntax something like this.

<% =ClassName.StaticMethod([Arguments]) %>

So in the above examples I have used the above syntax in javascript where I am retrieving a text from the resource file and passing it to a javascript function called “showText”. Also I have made use of the above syntax in javascript’ alert message as well. The code snippets are pasted below.

// Passing the localised string retrieved from the server to a javascript function.
showText('<% =ResourceManagerUtility.GetString(Constants.PLEASE_WAIT) %>')

// Passing the localised string retrieved from the server to a javascript alert box.
alert('<% =ResourceManagerUtility.GetString(Constants.
SCREWED_UP_REQUEST) %>');

Also the same syntax is used in between html tags and for assigning the text value of a label control. The code is pasted below.

<!--Writing the localised text in a table' column-->
<tr>
<td class="SubSection">
<% =ResourceManagerUtility.GetString(Constants.OPEN_CONNECTION) %>
</td>
</tr>
<!--Assigning the localised string to the text property of a label control-->
<label id="noRecordsFound" runat="server" visible="false" style="font-size:large;"><% =ResourceManagerUtility.GetString(Constants.NO_RECORDS_FOUND) %></label>

One could see from the above code snippet that how easy is to access server functions in javascript, html tags and also in server control tags.

Possible mistake while using the above syntax can be as follows.

  • Not making use of the ‘=” symbol before the server code. E.g. is shown below.
  • <% ResourceManagerUtility.GetString(Constants.OPEN_CONNECTION) %>

    The above statement can throw the below pasted error if used in javascript or in html or with server controls.

    Compilation Error

    Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
    Compiler Error Message: CS1002: ; expected

  • Next thing what any sane person would do on seeing the error is placing a “;” (semi colon) at the end of the expression as shown below.
  • <% ResourceManagerUtility.GetString(Constants.OPEN_CONNECTION); %>

    The above code is perfectly correct if it is placed in between html tags or used along with server control tags. The modified code without the “=” sign is shown below.

    <!--Writing the localised text in a table' column-->
    <tr>
    <td class="SubSection">
    <% ResourceManagerUtility.GetString(Constants.OPEN_CONNECTION); %>
    </td>
    </tr>
    <!--Assigning the localised string to the text property of a label control-->
    <label id="noRecordsFound" runat="server" visible="false" style="font-size:large<% ResourceManagerUtility.GetString(Constants.NO_RECORDS_FOUND); %></label>

    But the same code without the “=” will not work if used in javascript. The code using the “alert” statement is modified (without “=”) and pasted below.

    alert('<% ResourceManagerUtility.GetString(Constants.
    SCREWED_UP_REQUEST); %>');

    The above code will invoke the method and get the value but the alert message will be a blank one. The reason is the absence of the “=” sign. The “=” sign means an assignment, as the “=” sign is missing; the value is not getting assigned. So if you are trying to get some value from the server side in javascript then one has make use of the code with ‘=” sign and without the semicolon.

    alert('<% =ResourceManagerUtility.GetString(Constants.
    SCREWED_UP_PENDING_REVIEW) %>')

  • “=” sign along with “;” in javascript or html or along with sever controls. If someone is using “=” along with “;’ in the expression then the below error will be thrown.
  • Compilation Error

    Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
    Compiler Error Message: CS1026: ) expected

    The error prone code is shown below.

    // Error prone javascript code having both = and ;.
    alert('=<% ResourceManagerUtility.GetString(Constants.
    SCREWED_UP_PENDING_REVIEW); %>');

    <!--Error prone HTML code with = and ; used together-->
    <tr>
    <td class="SubSection">
    <% =ResourceManagerUtility.GetString(Constants.
    OPEN_CONNECTION); %>
    </td>
    </tr>

    To avoid the error, either use “=” without “;” with inline code in javascript and “;” without “=” with inline code in html. To be on the safer side one can safely use only “=” sign along with inline code in both javascript and html tags as shown below.

    // Perfect and safest way to use the same technique
    alert('<% =ResourceManagerUtility.GetString(Constants.
    SCREWED_UP_PENDING_REVIEW) %>');

    <!--The same way as it is used in the javascript-->
    <tr>
    <td class="SubSection">
    <% =ResourceManagerUtility.GetString(Constants.
    OPEN_CONNECTION) %>
    </td>
    </tr>

    I would recommend the above approach that works with javascript, html tags as well as with server control tags. Just for the sake of knowledge you can keep yourself aware about the other ways as well, but while implementing please follow the common methodology which will help you to avoid hell lot of problems.

    Also in some blog I have read someone saying that only static methods can be accessed, this is not at all true. One can very well access normal methods of a class by creating an instance of the class and then accessing them in inline code as shown below.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Dummy.aspx.cs" Inherits="MyProject.Dummy" %>
    <%@ Import Namespace="Utilities" %>
    <%@ Import Namespace="StaticContents" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
    <title>Showing normal method access in inline code.</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <% =dummyString%>
    <table>
    <% ResourceManagerUtility rmu = new ResourceManagerUtility();%>
    <tr>
    <td><!--Accessing an instance method and assigning the output in a table' column by making use of inline code.-->
    <% =rmu.GetString(Constants.NO_RECORDS_FOUND) %>
    </td>
    </tr>
    </table>
    </div>
    </form>
    </body>
    </html>

    One can notice a line something like this.

    <% =dummyString%>

    What I am doing in the above line of code is accessing a server side variable and displaying the value. Below is the code behind file where the variable is declared.

    public partial class DisplayFile : System.Web.UI.Page
    {
    protected string dummyString = "Dummy String";
    // Other code for the page goes here.
    }

    One point to note here is that one can only access protected or public variables. If one tries to access private variables in inline code the below pasted error will crop up.

    Compilation Error

    Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
    Compiler Error Message: CS0103: The name 'dummyString' does not exist in the current context

    The same applies to methods also. One cannot access private code behind methods in inline code. The only restriction which applies in the case of inline code is one cannot access private members. Static, protected and public members can very well be accessed.

    The only reason which I find why many are saying that only static methods can be used in inline codes is that one need not create a member variable to access the return value of a function. Other than that I don’t see any logic in saying this. One can very well access any protected, public and static members (variables, methods) of a code behind file or a class.

    Hope the above e.g. clears some of the myths associated with accessing server side methods, variables and classes.

    Wednesday, March 4, 2009

    Automatic Properties – Features of C# 3.0 (Part - 2)

    In the first part of this blog we saw Extension Methods. This blog will try to shed some light on another feature introduced in C# 3.0 called Automatic Properties.

    What is Automatic Properties?

    Imagine you have a Car class with ModelName, Color, NumberOfDoors, SeatingCapacity etc as their properties. Your typical class structure will look something shown below.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace AutomaticPropertyDemo
    {  
        public class Car  
        {    
            private string _modelName;    
            private string _color;    
            private int _noOfDoors;    
            private int _seatingCapacity;    
            public string ModelName    
            {        
                get { return this._modelName; }        
                set { this._modelName = value; }    
            }    
            public string Color
            {
                get { return this._color; }        
                set { this._color = value; }    
            }    
            public int NumberOfDoors    
            {        
                get { return this._noOfDoors; }        
                set { this._noOfDoors = value; }    
            }    
            public int SeatingCapacity    
            {        
                get { return this._seatingCapacity; }        
                set { this._seatingCapacity = value; }    
            } 
        }
    }

    From the above code one can see, to implement a single property we have to declare a private variable, set the value to the variable using the “value” keyword in the set block and then finally use the return keyword to return the stored value. The same code applies to all the properties. Just to implement four properties I had to write nearly 62 lines of code. Huh, that’s a lot of code which doesn’t do anything great. And I hate to write these kind of code which dumb in nature.

    When I started using properties in my early days of .NET career, I use to think, if the system can infer the exact type of the object passed in the “value” keyword in a property and appropriately cast it to the variable, then why can’t it infer the same using the property’ signature and automatically generate codes to assign and return the values of a property, after all the codes are pretty much same. And if there is a need to implement some logic inside the properties only then the user should write his/her own implementation of the get and set property. If you were also thinking the same then with C# 3.0 Microsoft has come up with Automatic Properties to help developers like you and me.

    With automatic properties one need not declare a member variable to store the values of the properties and need not write the same code repeatedly again and again. The above code can be rewritten like the one shown below using automatic properties.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace AutomaticPropertyDemo
    {  
        public class Car  
        {    
            public string ModelName { get; set; }    
            public string Color { get; set; }    
            public int NumberOfDoors { get; set; }    
            public int SeatingCapacity { get; set; } 
        }
    }

    From the above code you can see the nearly 62 lines of code has been reduced to just 16 lines of code. There was no need to declare a member variable, no need to write the same repetitive code for assigning and returning the value. One has to just declare the property with a get and set key word. The only restriction which applies here is that automatic properties should have both getters and setters.

    The next obvious question would be how would one can declare a get or set only property using automatic property. Its simple, qualify the set or get with the “private” access modifier. The below code shows the code snippet.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace AutomaticPropertyDemo
    {  
        public class Car  
        {    
            public string ModelName { get; set; }    
            public string Color { get; set; }    
            public int NumberOfDoors { get; private set; }    
            public int SeatingCapacity { private get; set; } 
        }
    }

    From the above code we can see the “NumberOfDoors” property has been declared as read only by qualifying the setter with private access modifier and the “SeatingCapacity” property is set only. In “SeatingCapacity” property the getter is declared private.With private or protected access modifier one can control the access level of automatic properties.

    With automatic properties one need not write tons of code just to declare simple properties. With get and set keyword one can declare a read/write property. The compiler will auto create the variables necessary to store the values. If there is a need in future to bring in some logic to the setter and getter, one can very well extend the code without much work.

    As quoted earlier it is a must to have both getter and setter in Automatic property. If either one, get or set, is missed the following error will be thrown by the compiler.

    'AutomaticPropertyDemo.Car.Color.set' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.

    Many people have asked me how to access the automatically created variable? Why would anyone access the auto generated variable? The aim of automatic property is to write terse codes, if you want to desperately access the values stored in the property then access it using the property name. The only reasonable reason when you would need to access the auto generated variable is when you have some logic embedded inside the getter/setter method. If you have some logic, then obviously one cannot make use of automatic properties, one has to go by the good old way of declaring member variables and making use of it in properties. If one plans to bring in some logic then obviously he has to take full control of the properties by declaring member variables for the properties and should not rely on the system’ auto generated variables. I hope the above reasoning is enough for people who want to access auto generated variables and as far as my knowledge goes there is no way of doing that.

    So what are you waiting for, start writing terse codes!!

    Know more

    Sandeep