Tuesday 31 January 2012

ASP.NET Search Records In GridView Footer And Highlight Results



Search Records In GridView Footer And Highlight Results using ajax in asp.net

In this example i am populating gridview without using sqlDataSource but by creating Sqlconnection and SqlCommand.

I've put a textbox for text to search in footer of gridview using footer template , and the search results are highlighted using regular expression, i m using AJAX for partial postback and update progress template to show search progress

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Search and highlight Results in Grdiview
</title>
<style type="text/css">
.highlight {text-decoration:none; font-weight:bold;
color:black; background:yellow;}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"
runat="server" />
<asp:UpdatePanel ID="UpdatePanel1"
runat="server">
<ContentTemplate>
<div>
<asp:GridView ID="grdSearch" runat="server"
BackColor="white" BorderColor="Aqua"
AutoGenerateColumns="false" ShowFooter="true"
OnRowCommand="grdSearch_RowCommand">
<FooterStyle BackColor="AliceBlue"
ForeColor="AntiqueWhite" />
<PagerStyle BackColor="#99CCCC"
ForeColor="#003399" HorizontalAlign="Left" />
<HeaderStyle BackColor="#003399"
Font-Bold="True" ForeColor="#CCCCFF" />

<Columns>
<asp:TemplateField HeaderText="FirstName">
<ItemTemplate>
<asp:Label ID="lblFIrstName" runat="server"
Text='<%# Highlight(Eval("FirstName").ToString()) %>'>
</asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtSearch" runat="server"
Width="70px"></asp:TextBox>
<asp:Button ID="btnSearch"
CommandName="Search"
runat="server" Text="Search"
Width="60px" />
</FooterTemplate>
</asp:TemplateField>
<asp:BoundField DataField="LastName"
HeaderText="LastName" />
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1"
runat="server">
<ProgressTemplate>
<br />
<img src="Images/ajax.gif"
alt="Searchig"  />
</ProgressTemplate>
</asp:UpdateProgress>
</form>
</body>
</html>

And the code behind first of all i m populating the Grid by making sqlconnection, Sqlcommand and fatching the data from database, than binding the data to grid view at Page_Load event after checking the page is not loading firs time by by checking flag of isPostBack
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;
using System.Data.SqlClient;

public partial class _Default : System.Web.UI.Page
{
string strConnection =
ConfigurationManager.AppSettings["ConnectionString"];
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}

}
private DataTable GetRecords()
{
SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select * from Employees";
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = cmd;
DataSet objDs = new DataSet();
dAdapter.Fill(objDs);
return objDs.Tables[0];

}
private void BindGrid()
{
DataTable dt = GetRecords();
if (dt.Rows.Count > 0)
{
grdSearch.DataSource = dt;
grdSearch.DataBind();
}
}

Now i've written a method to search the text within results of GridView, which user enter in the TextBox to search
private void SearchText(string strSearchText)
{
DataTable dt = GetRecords();
DataView dv = new DataView(dt);
string SearchExpression = null;
if (!String.IsNullOrEmpty(strSearchText))
{
SearchExpression =
string.Format("{0} '%{1}%'",
grdSearch.SortExpression, strSearchText);

}
dv.RowFilter = "FirstName like" + SearchExpression;
grdSearch.DataSource = dv;
grdSearch.DataBind();
}

Next step is to check the command in RowCommand event of grid view,if it is what u've defined in while creating the button in footer of grid by assigning the commandname property, if yes than get the text entered by user in textbox placed in footer of gridview by using findcontrol method and pass this text to the search method written earlier by making a call to that method
protected void grdSearch_RowCommand
(object sender, GridViewCommandEventArgs e)
{
System.Threading.Thread.Sleep(2000);
if (e.CommandName == "Search")
{
TextBox txtGrid =
(TextBox)grdSearch.FooterRow.FindControl("txtSearch");
SearchText(txtGrid.Text);
}
}

Now to highlight the search text in results i m using regexp and replacing the the words found with highlighted in yellow color
public string Highlight(string InputTxt)
{
GridViewRow gvr = grdSearch.FooterRow;
if (gvr != null)
{
TextBox txtExample =
(TextBox)grdSearch.FooterRow.FindControl("txtSearch");

if (txtExample.Text != null)
{
string strSearch = txtExample.Text;
//string Search_Str = txtGrid.Text.ToString();
// Setup the regular expression 
//and add the Or operator.

Regex RegExp =
new Regex(strSearch.Replace(" ", "|").Trim(),
RegexOptions.IgnoreCase);


//Highlight keywords by calling the delegate 
//each time a keyword is found.
return
RegExp.Replace(InputTxt, new MatchEvaluator(ReplaceKeyWords));

// Set the RegExp to null.
RegExp = null;

}
else
return InputTxt;
}
else
{
return InputTxt;
}
}

public string ReplaceKeyWords(Match m)
{
return "<span class=highlight>" + m.Value + "</span>";
}


Download the sample code attached

Sunday 29 January 2012

Hide/Show validator callout control using javascript

Hide/Show validator callout control using javascript

In my previous blog we saw how to call validation controls from javascripts. This blog we will see how to show and hide a ASP.NET AJAX’ (AJAXControlToolkit) ValidatorCalloutExtender control using javascript. Below is an aspx page with a validator callout control.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="AJAXControls" %>
<!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>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <!--ASP.NET Drop down control-->
        <asp:DropDownList ID="status" runat="server" >
            <asp:ListItem Selected="True" Text="Select" Value="0" />
            <asp:ListItem Text="One" />
            <asp:ListItem Text="Two" />
            <asp:ListItem Text="Three" />
        </asp:DropDownList>
        <!--ASP.NET Required Field Validator to validate the drop down.-->
        <asp:RequiredFieldValidator ID="statusValidator" runat="server" ErrorMessage="Please choose a value other than 'Select'"
            ControlToValidate="status" InitialValue="0" Visible="true">
        </asp:RequiredFieldValidator>
    <!--Validator callout control-->
        <AJAXControls:ValidatorCalloutExtender ID="statusValidator_ValidatorCalloutExtender"
            runat="server" TargetControlID="statusValidator">
        </AJAXControls:ValidatorCalloutExtender>
        <asp:Button ID="submit" Text="Submit" OnClientClick="javascript:return ValidatePage();"
            runat="server" />
    </div>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    </form>
</body>
</html>
The above code has a dropdown control with an ASP.NET required field validator control and a validator callout control attached to it. As soon as you click the submit button and if there is a validation error the error will be popped out in the validator callout control as shown below.
Error in Validator callout control
Popping of the error message in a validator callout control happens automatically. But there may be scenario where you would like to hide or show the validator control using javascript. The below sample code does exactly that.
<script language="javascript" type="text/javascript">
function ValidatePage()
{        
    //Function which calls the whole validation for the page.
    if (Page_ClientValidate())       
    {
        return true;
    }
    else
    {       
        hideValidatorCallout();
        return false;
    }
}
//User defined method which hides the AjaxControlToolkit ValidatorCalloutExtender control
function hideValidatorCallout()
{
    //Below code hides the active AjaxControlToolkit ValidatorCalloutExtender control.
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.hide();
    setTimeout(showValidatorCallout, 3000);   
}
function showValidatorCallout()
{
    //Gets the AjaxControlToolkit ValidatorCalloutExtender control using the $find method.
    AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout = $find('<% =statusValidator_ValidatorCalloutExtender.ClientID %>');
    //Below code unhides the AjaxControlToolkit ValidatorCalloutExtender control.
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.show(true);
}
</script>
From the above code we can see that there is a code something like this “AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout”. The _currentCallout property will hold the current validator callout control. Whenever there is a validation failure and if there is validator callout control associated with validator control, the _currentCallout property will be assigned the validator callout control. To hide the validator callout control you need to use the “hide”  javascript function along with the _currentCallout property as shown below.
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.hide();
At any given point the _currentCallout property will have only one validator callout assigned, this is to avoid the confusion or dirtiness which can arise by showing all the validator callout control. If all the validator callouts are shown when multiple validation fails then the screen will be cluttered with all the validator callouts popping here and there. To avoid this cluttered view this approach of showing only one validator callout control has been taken.
Similarly to show the validator callout control you can use the “show” javascript method along with _currentCallout property as shown below.
//Gets the AjaxControlToolkit ValidatorCalloutExtender control using the $find method.
    AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout = $find('<% =statusValidator_ValidatorCalloutExtender.ClientID %>');
    //Below code unhides the AjaxControlToolkit ValidatorCalloutExtender control.
    AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.show(true);
But the above code if used just like that can throw the following error.
Microsoft JScript runtime error: 'this._popupBehavior' is null or not an object
The reason why this happens is that we have not called either ValidatorEnable or ValidatorValidate javascript functions. These two functions set the necessary things, like _popupBehavior property, for the validator control to work properly. Validator callout controls are not meant to be shown directly they are actually extender controls which extend the functionality of the validation control and these controls are shown automatically when a validator control’ validation condition fails. So if you want to show a validator callout function just call ValidatorEnable or ValidatorValidate javascript function.
That’ about it, on how to hide and show validator callout controls using javascript. I know I have not mentioned anything about “$find” javascript function. We will have a discussion on this in my subsequent blog. For the time being just understand it as a shortcut method to find a component. In our next blog we will see how to set focus to a particular tab in the AjaxControlToolkit’ tab container control.
Some important methods of ValidatorCallout controls
Methods/Properties Description
_getErrorMessage() Gets/returns the error message
get_closeImageUrl() Gets/returns the close image url at the top rightmost corner of the validator callout control. Default is an x mark.
get_isOpen() Gets/returns a boolean value indicating whether the validator callout is opened or not.
get_warningIconImageUrl() Gets/returns the warning icon image’ url. Default is an exclamation mark inside a triangle.
get_width() Gets/returns the width of the validator callout control.
hide() Function to hide the validator callout control.
set_closeImageUrl(imageUrl) Function to set the close image url. One can use this method to change the default X mark.
set_warningIconImageUrl(imageUrl) Function to set the warning image. One can use this function to change the default exclamation image used for warning.
set_width(int) Function used to set the width of the validator callout control.
show() To show the validator callout control.
_closeImageUrl Property to get/set the close image.
_warningIconImageUrl Property to get/set the warning image.
_width Property to get/set the width of the validator callout control
_popupBehavior Property using which one can work with the pop up behaviour of the validator callout control.
_errorMessageCell Property using which one can modify the error message.
Some methods of ValidatorCallout._popupBehavior property
Below are listed few of the _methods of _popupBehavior property of validator callout function. These methods are available with only _popupBehavior property. If one wants use these methods then one has retrieve the _popupBehavior property from  validator callout control by any of the following two means shown below.
//Retrieving the validator callout control using the $find helper method.
var valCallout = $find('<%=statusValidator_ValidatorCalloutExtender.ClientID %>');
//Get the _popupBehavior property in a variant object and then
//use the required methods.
var popUpBehavior = valCallout._popupBehavior;
popUpBehavior.set_x(10);
popUpBehavior.set_y(20);
//Directly use the methods along with the _popupBehavior property as shown below.
valCallout._popupBehavior.set_x(20);
valCallout._popupBehavior.set_y(30);
After retrieving the _popupBehavior property by any of the above means you can use the following methods.
Methods/Properties Description
get_x() Method to get the X coordinates of the validator callout control
get_y() Method to get the Y coordinates of the validator callout control.
get_visible() Methods that returns a boolean value specifying whether the validator callout control is visible or not.
set_x(x_coordinate) Method to set the X coordinate for the validator callout control. Method takes an integer value as an argument.
set_y(y_coordinate) Method to set the Y coordinate for the validator callout control. Method takes an integer value as an argument.
Some methods of ValidatorCallout._errorMessageCell property
Since _errorMessageCell returns a TD (cell) object there is nothing much new it has all the methods/properties corresponding to a cell object. One use of this property is to change the error message of the validator callout extendor control using javascript. To change the error message using javascript see the code below.
//Retrieving the validator callout control using the $find helper method.
var valCallout = $find('<%=statusValidator_ValidatorCalloutExtender.ClientID %>');
//Get the error message cell.
var messageCell = valCallout._errorMessageCell;
//Changing the error message.
messageCell.innerHTML = "Changed:)";
Mail from my blog reader
Recently one of my blog reader mailed me across some problems he was facing with validator callout control. For the benefit of the readers I am pasting the mail chain discussion here, with prior permission from the reader who mailed me.
Hey Sandeep, how are you?
I've read your amazing article on:
http://sandblogaspnet.blogspot.com/2009/04/
setting-focus-to-particular-tab-in.html
thank you very much, it really help me!
So, I want to call all validators, and them call the specific callout,
since we can access  Page_Validators[validatorIndex]...
I could execute all the validators, but now I need to know the name of
validator to call the callout.
var validator = Page_Validators[validatorIndex];
do you know how to get the id of the validator?
validator.Id ? validator.ClientId ?
thank you !
this is my solution for now:
<script language="javascript" type="text/javascript">
    var Page_Callout = new Array("<%
=statusValidator_ValidatorCalloutExtender.ClientID %>");
    function ValidatePage() {
        if (typeof (Page_Validators) == "undefined") return;
        var noOfValidators = Page_Validators.length;
        for (var validatorIndex = 0; validatorIndex < noOfValidators;
validatorIndex++)
        {
            var validator = Page_Validators[validatorIndex];
            ValidatorValidate(validator);
            if (!validator.isvalid) {
                var tabPanel = validator.parentElement.control;
                var tabContainer = tabPanel.get_owner();
                tabContainer.set_activeTabIndex(tabPanel.get_tabIndex());
                showValidatorCallout($find(Page_Callout[validatorIndex]));
                return false;
            }
            return true;
        }
    }
    function hideValidatorCallout() {
        AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.hide();
    }
    function showValidatorCallout(currrentCallout) {
        AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout =currrentCallout;
        AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout.show(true);
    }
</script>
-- My reply--
Hi XYZ,
If I am not wrong when you are calling the function "showValidatorCallout" it doesn't show the validator callout in the tab? Am I right? If yes I have also faced the same problem. I solved this by a dirty hack. So what I did is something like this.
ValidatorEnable(dropDownValidator); //Calling the validator callout for the first time. Just a dummy call.
if (!dropDownValidator.isvalid)
{
     setActiveTabIndex(0); //Method which sets the active index.
     hideCurrCallout(); //Method which hide the current validator callout
     ValidatorEnable(dropDownValidator); //Calling ValidatorEnable method for the second time.
}
Hope this helps. So when you work with tab you have to use the above hack to display validator callout control. I didn't get much time to find out the reason behind but will try find out.
--Response from the reader--
Hey Sandeep, thanks...
I've another problem with the callout's... Please, take a loot in that
image attached.. do you have this problem ?
When the field is in the right side... the callout create scrolls and
expand the width of the page :(
Do you know how to avoid this ?
--My reply-- Hope your previous problem has been solved. This is the auto behaviour of the browser where if something is dynamically created and it exceeds the width of the browser it will give you a scroll bar. For this you can set the X and Y coordinates of the callout control so that they won't exceed the width of the browser. To set the X and Y coordinates you can use the following code.
//Retrieving the validator callout control using the $find shortcut method.
var valCallout = $find('<%=statusValidator_ValidatorCalloutExtender.ClientID %>');
//Setting the X coordinates
valCallout.validatorCallout._popupBehavior.set_x(xCordinates);
//Setting the X coordinates
valCallout.validatorCallout._popupBehavior.set_y(yCordinates)
or you can use the below code.
AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout._popupBehavior.set_x(xCordinates);
AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout._popupBehavior.set_y(yCordinates)
Hope this solves your problem.
--Reader response--
Hi Sandeep,
Yeah... you solve the problems :)
thank you again.
cheers,

Trim function in javascript

Trim function in javascript

Trim function in javascript
One important function which we miss very much while working with string object in javascript is the trim function. Not anymore. If you are using ASP.NET you can very well make use of “ValidatorTrim” function to trim both leading and trailing spaces. E.g. is shown below.
var testString = '   Test trail    text    ';
//Below code removes spaces before and after the word.
testString = ValidatorTrim(testString);
In the above e.g. ValidatorTrim removes the leading and trailing spaces in the “   Test text  ” string and returns “Test Text” as the string. So whenever you need to trim spaces in javascript then go ahead and use “ValidatorTrim” function to trim spaces.
If you keep a breakpoint on the ValidatorTrim function and step into the function you can see the following code.
function ValidatorTrim(s) {
    var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
    return (m == null) ? "" : m[1];
}
One can see from the above code that Regular Expression is used to pick out the text without the trailing and leading spaces. People who are not ASP.NET developers can very well implement the same logic and can have their own javascript trim function.

Data type validation using validation control

Data type validation using validation control

While developing ASP.NET application you would have come across scenarios where you would like to validate whether the value entered is of a particular data type. The options available with an ASP.NET developer is to write javascript functions to check whether the entered value complies with a data type or make the page postback and check the data type in server side. These two options are time consuming. Is there any simple way of doing this? The answer is to the question is “YES”. One can make use of compare validator to accomplish the task very easily. Lets see how.
To compare whether the entered value is of a particular data type one should make sure that the “Operator” property of compare validator should be “DataTypeCheck” and the “Type” property should be the data type you want to check. These two things are the only requirement to validate the data type. Compare validator supports validation for Currency, Date, Double, Integer and String data type. Below is a sample code which tries to check all these data types.
Enter string: <asp:TextBox ID="txtString" runat="server"></asp:TextBox>
<asp:CompareValidator ID="cmpVldString" runat="server" ErrorMessage="Not a valid string." ControlToValidate="txtString"
Type="String" Operator="DataTypeCheck"> </asp:CompareValidator>
<br />
Enter integer: <asp:TextBox ID="txtInt" runat="server"> </asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" runat="server" ErrorMessage="Not a valid Integer." ControlToValidate="txtInt"
Type="Integer" Operator="DataTypeCheck"> </asp:CompareValidator>
<br />
Enter double: <asp:TextBox ID="txtDouble" runat="server"> </asp:TextBox>
<asp:CompareValidator ID="CompareValidator2" runat="server" ErrorMessage="Not a valid double." ControlToValidate="txtDouble"
Type="Double" Operator="DataTypeCheck"> </asp:CompareValidator>
<br />
Enter date: <asp:TextBox ID="txtDate" runat="server"> </asp:TextBox>
<asp:CompareValidator ID="cmpVldDate" runat="server" ErrorMessage="Not a valid date." ControlToValidate="txtDate"
Type="Date" Operator="DataTypeCheck" > </asp:CompareValidator>
<br />
Enter currency: <asp:TextBox ID="txtCurrency" runat="server"> </asp:TextBox>
<asp:CompareValidator ID="cmpVldCurrency" runat="server" ErrorMessage="Not a valid currencys." ControlToValidate="txtCurrency" Type="Currency" Operator="DataTypeCheck" > </asp:CompareValidator><br />
<asp:Button ID="Button1" runat="server" Text="Button" />
In the above code sample you can see that I am checking the datatype for string, Integer, date, double and finally currency. Isn’t it so easy to check the data type?
Now since we are validating date you would like to check against a particular format say “DD/MM/YYYY”. The default date format against which the compare validator checks the date is “YYYY/MM/DD”. One way specify the date format is to assign the page’ culture to the required culture which supports your date format. Say we want to check “DD/MM/YYYY” then we can set the following in the code behind.
protected void Page_Load(object sender, EventArgs e)
{
    Page.Culture = "hi-IN";
In the above code we are setting the culture for the page as Hindi-India which will accept the date in “DD/MM'/YYYY” format. Another way specifying the format in compare validator is to assign culture to the control which is specified in “ControlToValidate” property of the compare validator. For e.g. you have date picker assigned to a compare validator then assigning the culture or date format to the date picker will do the trick. As such there is no way to specify date format or culture to a compare validator.

Calling web service using javascript

Calling web service using javascript. Part -3

In the part 1 of this blog we saw how to invoke web service methods using pure javascript and in part 2 we made use of web service behavior to invoke web methods. The previous two blogs were not dependent on server technologies used by the user but this blog will have that constraint because we will have a look at how to invoke web methods using “ScriptManager”. “ScriptManager” is an ASP.NET server side control which is key to AJAX functionality in ASP.NET. Without any further delay let’ see our first web method invocation using “ScriptManager”. For this blog we will making use of the same web service as we have used in our previous two blogs. Below is the code for the first web service method we are going to invoke.
namespace ScriptManagerService
{
    //The attribute which makes the web service callable from script.
    [System.Web.Script.Services.ScriptService]
    public class TestService : System.Web.Services.WebService
    {
        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}
The above web service code is pretty straight forward. We have a simple “HelloWorld” method which returns a string. What makes this web service special is the “[System.Web.Script.Services.ScriptService]” attribute added on top of the “TestService” web service class. The attribute makes the web service callable from JavaScript. Also when the proxy classes are generated the attribute generates JavaScript object corresponding to the web service class. Once the web service is created now we need to create our web page to invoke the web method. Create a new aspx page and add a “ScriptManager” control to it. Sample aspx page with the “ScriptManager” tag is added below.
<body>
<script language="javascript" type="text/javascript">
function invokeSimpleWebMethod()
{
    ScriptManagerService.TestService.HelloWorld(handleResult);    
} 
 
function handleResult(result)
{
    alert(result);
}
</script>
   <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="scrMgr" runat="server">
            <Services>
                <asp:ServiceReference Path="TestService.asmx" />                
            </Services>
        </asp:ScriptManager>
        <asp:Button ID="btnHW" runat="server" Text="Hello World" OnClientClick="invokeSimpleWebMethod();" />
    </div>
    </form> 
</body>
In the above code we can see that we have a “ScriptManager” server control added. And inside the “Services” tag we have added reference to our local web service using the “ServiceReference” tag. The path attribute of the “ServiceReference” tag has the url of the web service which needs to be invoked. You can add multiple web services by adding additional “ServiceReference” tags. What ASP.NET does here is that it generates JavaScript proxy classes for each of the web services mentioned in the “ServiceReference” tag. All the auto generated JavaScript proxy classes derive from “Sys.Net.WebServiceProxy”.
Also we have an ASP.NET Button server control which calls a “invokeSimpleWebMethod” javascript method on its “OnClientClick” event. In the “invokeSimpleWebMethod” javascript method we have made use of the namespace (in which the web service is defined) followed by the web service name and finally the method name which needs to be invoked. Behind the scene ASP.NET has done the extra work of registering the namespace and creating the proxy classes and also adding the methods defined inside the web service into a proxy JavaScript class. If you notice the “HelloWorld” method takes an argument. The argument is nothing but the name of the JavaScript function which needs to be invoked when the web service method has been successfully executed and results are returned to the browser. You can also pass the name of the function which needs to be invoked when the web service method invocation request fails. We will see the same shortly. The “handleResult” JavaScript method gets called when the asynchronous request is successfully returned. The method gracefully displays the result in an alert message box.
That’ about how to use the “ScriptManager” server control to invoke a web service methods i.e. namespace followed by class name followed by the method name. One thing to note is that “ScriptManager” control can only be used to call web services in the same domain. Now lets see how to pass parameters to web methods.
Passing parameters to web method
We will use the following web method to see how we can pass parameters by using “ScriptManager”.
[WebMethod]
public string CombineName(string firstName, string midleName, string lastName)
{
      return string.Concat(string.Concat(firstName, " - ", midleName), " - ", lastName);
}
The above method is pretty straight and it is the same method which I have used in my previous blog. The method takes three string arguments and concatenates them and returns them as a single string. Now lets see how we can pass the three parameters from JavaScript.
Below is the JavaScript method which invokes the web method with the three string parameters.
function webMethodWithParams()
{    
    ScriptManagerService.TestService.CombineName("Sandeep", " ", "P.R", handleResult, handleError);
}

In the above JavaScript function we are invoking the “CombineName” method the same way we invoked the “HelloWorld” web method. But the difference here is that instead of the callback function as the first argument we are passing the arguments first, followed by the success callback function name and then the failure callback function. The funda behind is simple, if your web method accepted three parameters pass them first in the same order as defined in the web method followed by the callback methods. Similarly if the web method takes different number of parameters then make sure that, that many number of parameters are passed first followed by the success callback function. Success callback and error callback functions are optional. Our “handleError” javascript function looks something like this.
function handleError(error)
{
    alert(error.get_message());
}
The above “handleError” javascript function is pretty straight forward. It takes an error object as one of the argument. The error object passed by the system has various methods and properties to retrieve the details of the exception happened on the server side. Some of the methods and properties are as follows.
  1. get_exceptionType method or _exceptionType field/property can be used to get the type of exception raised by the server like “System.Exception”.
  2. get_message method or _message field/property can be used to get the error message returned by the server.
  3. _stackTrace field/property or get_stackTrace method can be used to get the stack trace of the error from the server.
  4. get_statusCode method or _statusCode field/property can be used to retrieve the HTML status code returned from the server.
The error object which is passed to the “handleError” JavaScript function is of type “Sys.Net.WebServiceError”. “Sys.Net.WebServiceError” is a simple class with the above explained methods or fields/properties.
Now the next step is to pass complex objects from JavaScript to a web method. Lets see how that can be accomplished.
Passing complex objects
Let see the code of the web method which accepts a complex object and processes it.
[WebMethod]
public string GetCar(Car car)
{
    return "Model: " + car.Model + ", Color: " + car.Color; //", Cubic capacity: ";//+ car.CC + 
}
The above web method doesn’t have rocket science in it, it just takes a complex object of type “Car” and concatenates the properties and returns it as a string. Now lets the “Car” class. Its same as that we have used in our previous examples.
public class Car
{
    public string Model
    {   get; set; }          
 
    public string Color
    { get; set; }
 
    public Engine CarEngine
    { get; set; }
}
 
public class Engine
{
    public int CC
    { get; set; }
    public int Cylinders
    { get; set; }
}
The “Car” class has three properties namely “Model”, “Color” and “CarEngine”. “Model” and “Color” are of type string and “CarEngine” is again a complex object of type “Engine”. The “Engine” class has two properties of type int namely “CC” and “Cylinders”. The above “Car” class is the one which we will be passing to the web method from within JavaScript using ScripManager. The code is pasted below.
function sendComplexObject()
{
    //Create a new Object and assign the same properties as those in the Car class.
    var car = new Object();
    car.Model = "Ferrari California"
    car.Color = "Ferrari Red"
    car.CarEngine = new Object()
    car.CarEngine.CC = 4500
    car.CarEngine.Cylinders = 12
    //Execute the web method.
    ScriptManagerService.TestService.GetCar(car, handleResult, handleError);
}
In the “sendComplexObject” method we are first creating a “Car” object by creating an object of type “Object”. Then to that object we are adding all the properties that the “Car” class has. Since JavaScript is a dynamic language you can add all the properties by just giving the name and the value. As the “Car” class has another complex object, Engine, as one of its property named “CarEngine” we are also creating the complex engine object also the same way. Once we have created the object we are finally executing the web method in the final line of code. Isn’t simple to pass complex objects from JavaScript to server. To help us to do write such a simple code the ScriptManager does the extra work converting the JavaScript objects to server objects.
Below is the JSON way of creating the complex Car object.
function sendComplexObject()
{
    //Create an object of type "ScriptManagerService.Car" and pass all the properties 
    //as a javascript string array.
    var car = new ScriptManagerService.Car({"Model" : "Ferrari California", "Color" : "Ferrari Red", "CarEngine" : {"CC" : "100", "Cylinders" : "5"}})
    //Invoke the web method.
    ScriptManagerService.TestService.GetCar(car, handleResult, handleError);
}
In the above code we are trying to create a “ScriptManagerService.Car” object. This is possible because the ScriptManager generates the Proxy classes automatically for us. Now lets see handling a complex type returned from the server. It also is quite simple.
Handling a complex object returned by the server
Lets see the web service which returns the complex object.
[WebMethod]
public Car GetCarObject()
{
    return new Car
    {
        Model = "Ferrari",
        Color = "Ferrari Red",
        CarEngine = new Engine { CC = 2500, Cylinders = 8 },
        test = "test"
    };
}
The above web method does the hard work of creating a car object and returning the same. We are going to invoke the above web method using the ScriptManager and use the very complex object in JavaScript. The JavaScript code is pasted below.
function receiveUseComplexObject()
{
    //Invoking the web method that returns complex object.
    ScriptManagerService.TestService.GetCarObject(handleResult, handleError);
}
 
//Modified handleResult function
function handleResult(result)
{
    //Using the complex object returned by the web method in JavaScript.
    var carDef = "Model: " + result.Model + ", Color: " + result.Color + ", Engine-CC: " + result.CarEngine.CC;
    carDef += ", Engine-Cylinders: " + result.CarEngine.Cylinders;
    alert(carDef);
}
In the “receiveUseComplexObject” we are not doing any drastic than invoking the “GetCarObject” web method. The main work is done by the modified “handleResult” function. The web method returns a “Car” object, the parameter of the “handleResult” also is the JavaScript proxy “Car” object representing the server object. The ScriptManager does all the work of converting the returned object as a JSON “Car” object. This is why we are able to use the properties of the “Car” object as we would do in a normal OOPS programming language.
Calling methods in a page
Using “ScriptManager” one can access method of a web page as well. One catch here is that you can execute only static page methods. To call a page method from JavaScript by making use of “ScriptManger” you need to add the “WebMethod” attribute to the method you want to call. Lets see “.cs” file of a web page.
public partial class TestPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {    }
 
    [System.Web.Services.WebMethod]
    public static string HelloWorld()
    {
        return "Hello world";
    }        
}
As mentioned above, we have added the “WebMethod” attribute to a static method and that’ it you need to do to make a page method callable by “ScriptManager”. In “ScriptManager” you need to set “EnablePageMethods” property to “true”. What this property does is it generates a “PageMethods” JavaScript class which has the necessary code to call all the static page methods which are decorated by the “WebMethod” attribute. Lets see the ASPX page and the JavaScript.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebSerCalServiceMngr.aspx.cs" Inherits="WebServiceUsingJS.WebSerCalServiceMngr" %>
 
<!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>Untitled Page</title>
</head>
<body>
<script language="javascript" type="text/javascript">
function callPageMethods()
{
    PageMethods.HelloWorld(handleResult);
}
</script>
 
<form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="scrMgr" runat="server" EnablePageMethods="true">   
        </asp:ScriptManager>
<asp:Button ID="Button3" runat="server" Text="Call page method." OnClientClick="callPageMethods();" />
    </div>
    </form>
</body>
</html>
In the above code we have set “EnablePageMethods” property to true and on the click of a button we are calling “callPageMethods()” JavaScript function. Inside the “callPageMethods” JavaScript function we are making use of “PageMethods” proxy class to execute our page method. So with “ScriptManager” doing all the extra work at the back, as a developer we are having great time.

Try to know more