Rajeeshcv.com

Sharing my knowledge

ASP.NET AJAX - Calling server side methods from client side

ASP.net AJAX has got nice bridging between your server side and client side technologies. Using the ASP.net AJAX you can easily call a method in a page. The restriction here is that, the methods your are trying to call should be static and public.

This feature(calling server side static method) is not enabled by default, so you have to manually enable this and it is very very simple; just set the "EnablePageMethods" property of the "ScriptManager" to true like this

 

 

 

 

<asp:scriptmanager id="ScriptManager1" runat="server" enablepagemethods="true">      </asp:scriptmanager>

After this, create a public static method in your asp.net page and decorate it with WebMethod(System.Web.Services.dll) and ScriptMethod(System.Web.Extensions.dll) attributes. For example I have created a static method called "GetTime()" which returns current time as string.

	
public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        [WebMethod]
        [ScriptMethod]
        public static string GetTime()
        {
            return DateTime.Now.ToLongTimeString();
        }
    }  

Now you have configured everything correctly and I will show you how to call this method from the client side.

Earlier you have set the "EnablePageMethods" property of "ScriptManager" to true, as a result of that a new object called "PageMethods" is created by the ScriptManager when the page is rendered. This object has all the public static methods in that page. So that you call the server side method like PageMethods.[ServerSideMethodName]. When calling this methods from client side you have to provide a callback function because here all the call scriptmanager made will be asynchronous, and this callback method will get the returned result.

Below is the sample code

	
	function callServerMethod()
        {
            PageMethods.GetTime(callBackMethod);
        }
        
        function callBackMethod(result)
        {
            alert(result);
        }

Complete aspx page looks like this

	
<body>     <form id="form1" runat="server">       <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">      </asp:ScriptManager>      <div>          <a href="javascript:callServerMethod()" >Call Server method</a>      </div>      <script language="javascript" type="text/javascript">      //<![CDATA[          function callServerMethod()          {              PageMethods.GetTime(callBackMethod);          }          function callBackMethod(result)          {              alert(result);          }      //]]>      </script>      </form>
</body>

Extra bits

In the above code you can see that I have placed link, when user click on that link a message is shown with the server time. So behind an asynchronous request is send to the server in this format (http://[sitename]/[MethodName]). Server in turn returns the result as JSON back to the client. Here is a screen shot from the firebug

image

image

There is optimization we have do here - you can see that, by default the request is a POST request, but in our case a POST request is heavy because we could have achieved the same using a GET request ( Difference between POST and GET ).

In order to change this request in to a GET request, we need to do a minor tweaking in the server side, set "UseHttpGet=true" parameter for the "ScriptMethod" attribute.

 
	[WebMethod]
        [ScriptMethod(UseHttpGet=true)]
        public static string GetTime()
        {
            return DateTime.Now.ToLongTimeString();
        }

After this you can see that, request is changed to a GET request

image


ASP.NET AJAX - Passing JSON object from client to server

  1. Part 1- Calling server side methods from client side

Read the Part 1 of this tutorial if you don't know how to call server side methods directly from client side.

In this post, I will explain how to pass data from client to server in JSON format.

Microsoft AJAX client library has built-in methods which helps in serializing and de-serializing JSON. The methods are defined in "Sys.Serialization.JavaScriptSerializer" class. In server side we have "JavaScriptSerializer"that will help you out to do the JSON serialization and de-serialization.

With the help of these two classes, we can easily do the data transfer. Suppose you have class called "Customer" in server side, which looks like this

 
using System;

namespace ServerClientInteration
{
    [Serializable]
    public class Customer
    {        
        public int ID { get; set; }

        public string Name { get; set; }

        public string Address { get; set; }
    }
}

This is our payload for this example, we are going to move this object from server to client and vice versa. For that I have exposed two static methods on the server side; one is for retrieving the customer details and the other is for updating the customer.

 
  public partial class _Default : System.Web.UI.Page
    {
        private static Customer customer = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (customer == null)
            {
                customer = new Customer();
                customer.ID = 1;
                customer.Name = "microsoft";
                customer.Address = "www.microsoft.com";
            }
            
        }

        [WebMethod]
        [ScriptMethod(UseHttpGet=true)]
        public static string GetTime()
        {
            return DateTime.Now.ToLongTimeString();
        }

        [WebMethod]
        [ScriptMethod(UseHttpGet = true)]
        public static string GetCustomer()
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Serialize(customer);
        }

        [WebMethod]
        [ScriptMethod]
        public static string UpdateCustomer(string jsonCustomer)
        {
            try
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                Customer cust = serializer.Deserialize(jsonCustomer);
                customer.ID = cust.ID;
                customer.Name = cust.Name;
                customer.Address = cust.Address;

                return "Updated";
            }
            catch(Exception Exception)
            {
                
            }

            return "Error occured while updating";
        }
    }

In the above code, you can see "GetCustomer" and "UpdateCustomer" methods. "GetCustomer" will serialize the static customer object and return it as JSON string; "UpdateCustomer" method accepts JSON string as input and that string is de-serialized in to a customer object and the static customer variable is updated with the new values. "UpdateCustomer" will return status message after the update.

Usually, we persist the customer in DB or some other states, but here for simplicity I have used a static variable which will simulate the persistence.

Now we need to call this from the client-side, for that I have two hyperlinks; one will get the customer from the server and other send the customer to the server.

Here is how the HTML looks like

 
<head runat="server"> 
<title>Untitled Page</title> 
<style type="text/css"> 
 
#result 
{ 
width: 250px; 
height: 300px; 
overflow: auto; 
border:1px solid #00d; 
} 
 
</style> 
</head> 
<body> 
<form id="form1" runat="server"> 
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"> 
</asp:ScriptManager> 
<div> 
<a href="javascript:callServerMethod()" >Call Server method</a> 
<hr /> 
<a href="javascript:getCustomer()" >Get Customer</a> 
<div id="result"></div> 
<hr /> 
<div> 
ID : <input type="text" id="custID" /><br /> 
Name : <input type="text" id="custName" /><br /> 
Adress : <input type="text" id="custAdd" /><br /> 
</div> 
<a href="javascript:updateCustomer()" >Update customer</a><br /> 
 
</div> 
<script language="javascript" type="text/javascript"> 
//<![CDATA[ 
 
function callServerMethod() 
{ 
PageMethods.GetTime(callBackMethod); 
} 
 
function callBackMethod(result) 
{ 
alert(result); 
} 
 
function getCustomer() 
{ 
PageMethods.GetCustomer(callBackGetCustomer); 
} 
 
function callBackGetCustomer(result) 
{ 
var customer = Sys.Serialization.JavaScriptSerializer.deserialize(result); 
var content = "<br />ID :" +  customer.ID + "<br />" + "Name : " + customer.Name + "<br />" + "Address : " + customer.Address; 
$get("result").innerHTML += content; 
} 
 
var clientCustomer = function(id,name,add){ 
this.ID = id; 
this.Name = name; 
this.Address = add; 
}; 
 
 
function updateCustomer() 
{ 
var id = $get("custID").value; 
var name = $get("custName").value; 
var address = $get("custAdd").value; 
 
var customer = new clientCustomer(id,name,address); 
var serializedCustomer = Sys.Serialization.JavaScriptSerializer.serialize(customer); 
PageMethods.UpdateCustomer(serializedCustomer,callBackUpdateCustomer); 
} 
 
function callBackUpdateCustomer(result) 
{ 
alert(result); 
} 
 
 
//]]> 
</script> 
</form> 
</body>

I think the above code is self explanatory, let me know if you have any difficulty in understanding this.

Hope this will gave some idea about passing JSON between client and server. I have uploaded the source code in my server and you can get it from here - http://www.rajeeshcv.com/download/ServerClientInteration.zip


Comet a.k.a server pushing

Have you ever thought about how chatting in Gmail works? I think it works using a programming technique called “Comet”.

What is comet programming

In web development, Comet is a neologism to describe a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it. Comet is an umbrella term for multiple techniques for achieving this interaction. All these methods rely on features included by default in browsers, such as JavaScript, rather than on non-default plugins - – Wikipedia

Last few days, I was reading about this technology and thought about sharing the information with you all. Please find the attached sample application which demonstrates how comet works using Asp.Net (Note: Right now it works only in firefox, fixes or patches to make it work in IE/Safari.. or all the browsers in this world are welcome J )

Please download it from here - http://www.rajeeshcv.com/download/Comet.zip


Attach to Any ASP.NET Web Server from Visual Studio in One Click

This is an update to my previous blog post Attach to Visual Studio Development Server with One Click.

The Visual Studio Macro from previous article doesn’t support IISExpress or IIS; it only supported the Visual Studio Development Server, more over it doesn’t detect latest Development Web Server “WebDev.WebServer40.exe”.

Now I have updated the Macro so that it will automatically detect the Web Server setting from the project properties and attach it accordingly.

Below is the code for the new Macro, I think it is self-explanatory

Public Sub AttachToWebServer()
    Dim attached As Boolean = False
    Dim project As EnvDTE.Project = GetStartupProject()

    If (project Is Nothing) Then
        MsgBox("Couldn't find a web project that can be attached")
        Return
    End If

    attached = AttachToProcess(project)

    If (Not attached) Then
        MsgBox("Couldn't attach to the process")
    End If
End Sub

Private Function GetStartupProject() As EnvDTE.Project
    Dim startUpProject As String = DTE.Solution.Properties.Item("StartupProject").Value

    For Each currentProject As EnvDTE.Project In DTE.Solution.Projects
        If currentProject.Name = startUpProject Then
            Return currentProject
        End If
    Next
    Return Nothing
End Function

Private Function AttachToProcess(ByVal project As EnvDTE.Project) As Boolean
    Dim serverProcessNamePattern As String
    ' Using either IIS express or IIS
    If project.Properties.Item("WebApplication.UseIIS").Value = "True" Then
        ' Using IIS Express
        If project.Properties.Item("WebApplication.DevelopmentServerCommandLine").Value.ToString().Length > 0 Then
            serverProcessNamePattern = ".*iisexpress.exe"
        Else ' Real IIS
            serverProcessNamePattern = ".*w3wp.exe"
        End If

    Else ' Assume development web server
        serverProcessNamePattern = ".*WebDev.WebServer\d+.EXE"
    End If

    Return AttachToWebServer(serverProcessNamePattern)

End Function

Private Function AttachToWebServer(ByVal serverProcessNamePattern As String) As Boolean

    Dim attached As Boolean = False

    For Each process In DTE.Debugger.LocalProcesses
        If (Regex.IsMatch(process.Name, serverProcessNamePattern)) Then
            process.Attach()
            attached = True
            Exit For
        End If
    Next

    Return attached
End Function

Read my previous article Attach to Visual Studio Development Server with One Click to understand how we can add this Macro as command to the Visual Studio toolbar.