Welcome to AJAX Tutorial in ASP.Net
What is AJAX?AJAX stands for Asynchronous JavaScript and XML. It is not a software or tool. AJAX can be said as a set of technologies which when used for a web app provides better performance and better user interaction by reducing full page postback and asynchronously handling the user requests using scripts.
Though AJAX takes advantage of JavaScript and XML, it is not compulsory that it should use these two languages. It can make use of any other technology/language but the basic working concept is the same.
The technologies that work together in AJAX are:
- XHTML and CSS mark-up
- DOM for display and interaction
- XML and XSLT(Extensible Style Sheet Language Transformation) for data interchange and manipulation
- JSON for marshalling objects
- XMLHttpRequest for asynchronous communication
- JavaScript for programming it all
- 3-tier client-server applications
For making asynchronous calls in a web app, it is necessary that an activex.dll is present at the browser (this dll may be different for different browsers, in case of IE it is activeX.dll). JavaScript can only invoke, but it cannot directly make asynchronous calls to the server. It is the dll that is present at the browser that is responsible for making calls directly. So the JavaScript just instantiates the dll and the dll does the remaining work. The steps that take place for making an asynchronous call are:
1. JavaScript function instantiates the dll
It then sends what is needed to the server through that dll.
Server processes and gives the result back to dll.
dll gives the result back to the JavaScript function.
JS DOM fills the result on the screen at the required control/controls.
These steps take place within a fraction of a second. Since only the required data is sent to the server instead of the whole page, it reduces the bandwidth and the result is obtained very quickly when compared to the total page postback. But all these things occur without the involvement of the browser. That is why it is not possible to go back to the previous state of the page by clicking the back button in the browser.
Evolution of AJAX
In the days of Web 1.0 there was almost no user interaction with the web pages. But with the advent of Web 2.0 the requirements grew more for better user interaction, rich media support, graphics etc. along with high performance. Developers are constantly trying out new ways to improve these features and at the same time improve performance. One such solution is to make asynchronous calls to the server instead of carrying all the data to the server and getting it back again which proves heavy on the connection as well as the processing at the server.
The term AJAX was coined around the year 2005 and from then only it was started being treated as a separate, special technology. Though the concept of AJAX was used by Microsoft with its ActiveX.dll much earlier, it really gained prominence when Google started using it. Google took the advantage of Activex.dll in Internet Explorer and used it in their sites to make asynchronous calls to the server. Soon other browsers too had their own dlls through which such calls can be made. AJAX is not specific only .NET or Java or any other language/technology. It is just a concept which can be used by any languages that support web development.
XMLHttpRequest is the key object of entire AJAX today. Normally every web request that we make is using browser and all its generated http format. This is purely synchronous which means that we have to wait till the response is given and then only perform the next task. This synchronous request includes the total web content to server. The server then processes this request and redirects the total web page content including the outputs, designs and instructions to the browsers. But these tasks are absolutely unnecessary when only a little change is needed at some particular control. So by using AJAX we can
- Avoid synchronous calls and add asynchronous calls
- Avoid total postback and do partial post back
- Reduce server tasks and improve client tasks
- Use variety of services
AJAX Demo without using ASP.NET library
Steps:
- Start a new website and delete default aspx page
- Add one html page called gettime.htm. Create a button and a div tag with default content.
- We must instantiate AJAX object once the page is loaded (this is a better practice). So go to OnLoad event of body tag and write the required code.
- On click of button invoke a JavaScript function. In this function write code to use XMLHttp created object and make call to aspx program that returns the server system time.
Along with this asynchronous call we must assign callback function
Now write callback function to receive data and update the div tag with results.
We must also create an aspx page that returns the sever time with or without design
The above tasks are for targeting different types of browsers and using complete AJAX functionality like JavaScript, CSS, XmlHttp and others. There are many (around 100) frameworks which are open source and also licensed which automates all this AJAX functionality and encapsulates most of the AJAX technologies. ASP.NET AJAX is one among such frameworks, which is free for consuming and developing AJAX applications.
The whole code for this demo is given below:
date.htm file (with JavaScript functions):
<html> <head>
<title>Universal AJAX</title>
<script language="javascript" type="text/javascript"> var xmlHttp;
function InitializeForAjax()
{
try
{
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest();
}
else if (window.createRequest) { xmlHttp = window.createRequest();
}
}
catch(e)
{
xmlHttp=null;
}
}
function OnButtonClick()
if(xmlHttp==null)
alert("Browser does not support AJAX");
//Open an async connection- true is for async, false for sync xmlHttp.open("POST", "Time.aspx", true);
//Wire-up event handler : callback xmlHttp.onreadystatechange=UpdateUI;//after call is
//returned, run UpdateUI xmlHttp.send(null);//send request without any content
}
function UpdateUI()
{
// if (xmlHttp.readyState == 1) {
// alert("Loaded")
// }
// if (xmlHttp.readyState == 2) {
// alert("Loading");
// }
// if (xmlHttp.readyState == 3) {
// alert("Interactive");
// }
if(xmlHttp.readyState==4) { if(xmlHttp.status=="200")
{
document.getElementById("divTime").style.display='block'; document.getElementById("lblTime").innerHTML="Date and
time is "+ xmlHttp.responseText;
}
else
alert("Communication error: Status="+xmlHttp.status);
}
}
</script> </head>
<body onload="InitializeForAjax()">
<input type="button" value="Get time asynchronously" onclick="OnButtonClick()"/>
<div id="divTime" style="display:none" > <label id="lblTime"></label>
</div> </body> </html>
Time.aspx
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("<b>" + DateTime.Now + "</b>");
}
ASP.NET AJAX
Till now we have seen AJAX which is common for any technology/language.
There are different types of AJAX for different technologies like MagicAJAX
AJAX.NET, ASP.NET AJAX etc. Out of these ASP.NET AJAX is the richest because it is cross-browser, cross-platform and also allows asynchronous calls in a very easier way. ASP.NET AJAX which is provide lsupport for AJAX in ASP.NET environment is specific to ASP.NET applications ( though it supports some other languages like PHP), but runs in cross-browser environment.
Benefits & Concerns of AJAX:
Benefits:
· Richer application functionality
· Better end-user experiences
· Decreased bandwidth utilization
· Improved scalability
Concerns:
· Increased complexity for developers
· Increased attack surface (it is more vulnerable as scripts can be injected to cause harm)
By using ASP.NET AJAX we can overcome these concerns to a large extent.
What is ASP.NET AJAX
· A Framework for building richer, more interactive, standards-based web experiences.
· High productivity AJAX development Framework
i. Fewer concepts, fewer lines of code
ii. Application and UI building blocks for common scenarios
iii. Works/builds on top of ASP.NET
· Easy to author, debug and maintain
i. Clean separation of content, style , behaviour and code
ii. Well integrated with design and development tools
· Seamlessly integrated application model
i. Works with ASP.NET pages and server controls
ii. Allows access to ASP.NET web services and components
· Standards based : Works cross-browser
ASP.NET AJAX versions
AJAX is not supported by .NET 1.0/1.1
ASP.NET AJAX 1.0 was introduced for .NET version 2.0
Atlas was the beta version of this 1.0 version in the years 2004/05
We have to download ASP.NET AJAX 1.0 from the site asp.net and install it in VS2005. To use AJAX in VS 2005 we have to select AJAX-enabled website while creating a new website.
In .NET 3.5 there is no need to install AJAX separately. It comes with in-built AJAX 1.0 version and also includes a few enhancements over the same version used in VS 2005. Every website that we create in VS 2008 is AJAX-enabled – so no need to select AJAX-enabled site while creating new website. All the AJAX settings are specified in web.config file.
ASP.NET AJAX is designed in two models:
· Client-centric model
· Server-centric model
Server-centric models are ASP.NET AJAX libraries that are present in server and perform all processing for data as well as design.
Client-centric model: We can ask ASP.NET AJAX at server only to produce data and perform design and other activities in client. This greatly improves the performance of application.
The AJAX client-side libraries are stored in sys.* namespaces
Components provided with .NET 3.5
· ScriptManager
· ScriptManagerProxy
· UpdatePanel
· UpdateProgress
· Timer
ScriptManager
ScriptManager is a component provided in .NET 3.5 AJAX Extensions. It is the starting point for ASP.NET AJAX pages.
Tasks of ScriptManager:
· Downloads JavaScript files to client
· Enable partial-page rendering using UpdatePanel
· Provides access to web services via client-side proxies
· Manages call-back timeouts and provides error handling options and infrastructure
· Provides registration methods for scripts
· Enables ASP.NET AJAX localization support
Every page requires one ScriptManager instance.
If master pages are used, then only one ScriptManager in master page will suffice for all the child pages. If any extra script is needed for any one child page then we have to use ScriptManager Proxy. Even if ScriptManager is not needed in a child page where there exists a ScriptManager in master page, then also we need a ScriptManager Proxy to suppress the functioning of ScriptManager.
A child page need not have ScriptManager Proxy unless and until we want to specify some additional settings like adding some scripts in child pages, ignoring partial page rendering in child pages etc.
UpdatePanel
The UpdatePanel control offers built-in functionality.
· It is a container that enables updatable region and async postbacks
· Controls placed within UpdatePanel control will cause an async postback, not a full page postback
· With UpdatePanel no special programming is needed at the client, but not at the server
Execution Process:
In ASP.NET AJAX, at server-side complete page execution takes place for both synchronous and asynchronous calls i.e. we cannot make aspx pages run partially.
But for asynchronous calls only the data required for async calls is sent to the server, then whole page processing takes place at server and finally only panel results are sent back to browser for update.
We can have multiple UpdatePanels in a page and also we can have nested UpdatePanels also. By default all Update Panels get updated if even one UpdatePanel requests for async postback i.e. from server the data of all UpdatePanels is carried to browser for update. To change this default behaviour we can change the UpdateMode property of
UpdatePanel to „conditional‟ (by default it is „always‟).
UpdatePanel update scenarios:
If the UpdateMode property of the UpdatePanel control is set to „Always‟, the UpdatePanel control‟s content is updated on every postback that originates from the page. This includes asynchronous postbacks from controls that are inside other UpdatePanel controls and postbacks from controls that are not inside UpdatePanel controls.
If the UpdateMode property is set to „Conditional‟, and when we call the update method of the UpdatePanel control explicitly
If the UpdateMode property is set to conditional, and when the UpdatePanel control is nested inside another UpdatePanel control, and the parent panel is updated.
If the UpdateMode property is set to „Conditional‟ and when a postback is caused by a control that is defined as a trigger property of the UpdatePanel control. In this scenarios, the control explicitly triggers an update of the panel content. The control can be either inside or outside the UpdatePanel control that the trigger is associated with.
Note: This control does not cause full page postback even if it is outside the UpdatePanel, though complete page processing takes place at server just like any other control in UpdatePanel. This is because that control is now treated as a part of the UpdatePanel it is associated with.
Benefits of using AJAX
· Powerful user interface
· Helps in partial page rendering
· Works cross-browser
· Rich internet applications
· Google, Live and Flickr etc. are examples
· Useful for both Web/Mobile platforms.
Browser-Compatibility
Most of the up-level browsers like IE, Chrome, Firefox, Safarti etc. are AJAX-supported browsers. But some older or down-level browsers may not support AJAX.
PageRequestManager
PageRequestManager is a class in ASP.NET AJAX library which manages partial page updates of UpdatePanel at the client-side. Whenever partial page rendering is enabled on the page, an instance of this class is available in JavaScript which enables us to write different methods which can programmatically control partial page updates at client side.
Methods of PageRequestManager
IsInAsyncPostback : Indicates whether asynchronous callback is in progress GetInstance: Returns reference to current PageRequestManager instance AbortPostback: Cancel the asynchronous callback that is currently in progress Add-*: Registers handlers for PageRequestManager events
Remove-*: Deregisters handlers for PageRequestManager events.
Demo- Using nested UpdatePanels and
PageRequestManager
To demonstrate the use of UpdatePanels, let us create a very simple shopping cart kind of application. The following steps should be observed for the purpose:
Create tables
For this we need two tables- Category and Products. The Category table consists of columns Id, Desc, Look(gives path of category image) and Remarks. The Products table consists of columns ProdId, Desc, Price, Qty, ProdCategoryId and ProdView(image of product). The ProdCategoryId refers to the Id in Category table. After preparing the required tables enter data in them
Create folders CatImages and ProdImages for the category and product images respectively. Place the relevant images in these folders.
Place ScriptManager and UpdatePanel on the form.
Then place a DataList or ListView in the UpdatePanel. This DataList is to display the info from the Category table. For this, add the Category table as its datasource and select the required columns.
For a proper display of this info, go to source view and make a few decorative changes in Item Template of the DataList. To display the images from the path specified in the table we have to take an ImageButton in Item Template and write its code in the following way:
<ItemTemplate>
<asp:ImageButton ID="Playerpic" runat="server" Height="150" ImageUrl='
<%# Eval("Look") %> ' />
//other controls for other columns
</ItemTemplate>
If horizontal alignment is preferred for the items in DataList then specify the RepeatColumns property to some number.
Place another UpdatePanel inside the main UpdatePanel. Place DataList2 inside it for displaying Products information. Choose data source as Products table and while selecting columns specify the following in where condition:
Column: ProdCatId, Operator:=, Source:Control, Control ID: DataList1
As in the case of DataList1, do the changes in source code for DataList2 also.
To capture the selected item value we have to write the following code in ItemCommand event of DataList1
DataList1.SelectedIndex = e.Item.ItemIndex;
In case it takes time for the images to load, we can show the progress of the operation by using the UpdateProgress.
Place UpdateProgress somewhere on the page and set its AssociatedUpdatePanelID to UpdatePanel1. To show the progress add some animating .gif image and some text in it.
If the user wishes to cancel the request in between we can provide that option by using the AbortPostBack method of PageRequestManager as following:
Place a LinkButton or Button in html. In OnClientClick event write the following function code:
function CancelBtn_OnClick() {
var x = Sys.WebForms.PageRequestManager.getInstance(); x.abortPostBack();
}
This program demonstrates the use of AJAX through UpdatePanels, UpdateProgress and also shows how the PageRequestManager can be used in our script.
ASP.NET AJAX Debugging
AJAX-enabled web applications‟ debugging is a challenging task. AJAX-enabled ASP.NET applications contain a mix of server code and client code. The browser can also request additional data asynchronously. This can make debugging very tough and complex but with tools and what VS.NET provides, it is possible to debug apps.
ASP.NET AJAX debugging can be done in following ways:
1. Enable debugging in configuration file
2. Use tracing on the server
3. Use the methods of the Sys.Debug class to set breakpoints and handle trace output
4. Enable debugging in your browser
5. Attach the Visual Studio debugger to your Internet Explorer instance, or use external tools to debug in other browsers
6. Use external tools to capture HTTP traffic
1. Enabling debugging in configuration file
We have to specify the compilation debug property to true in root web.config file as follows:
<configuration>
<system.web>
<compilation debug= “true” />
....
</system.web>
</configuration>
Note: Though for normal programs‟ debugging we can make debug= “true” in page directive, it does not work for ASP.NET AJAX.
Support for debugging in VS2008:
VS2008 has added debugging JavaScript just like normal C# code and we can now put breakpoints and break at particular location of client-side scripts also. But it should be remembered to enable the debugging option in browser and preferably browser should be Internet Explorer.
ToolsàInternet optionsàAdvancedàDisable Script Debugging –uncheck this option
After this we can put breakpoints wherever needed on the client-side script and start debugging. This works fine for normal client-side scripts, but for AJAX-enabled Web applications, it is not possible to debug the scripts which are called during partial page updates. So, we need some more methods to debug such scripts. We‟ll see about them in the later sections.
2. Using Tracing on the server
For this, we have to enable tracing=true in configuration file under the system.web tag.
<configuration> <system.web>
<trace enabled="true" pageOutput="true" />
If trace is set to true, it means that a trace is generated and if the pageOutput is true the tracing results will be appended to the page. But this does not work for aysnchronous requests i.e., ASP.NET AJAX does not show trace results at the end of the page ( though trace is generated in this case also).
Note: The trace can be observed in all browsers.
We can view the complete trace using trace utility.
Type trace.axd after the url of the application. Suppose the path is :
http://localhost/myajaxapp/default.aspx
then trace can be observed by typing
http://localhost/ajaxsports/default.aspx/trace.axd
By default there is a limit of 10 results for the results generated by trace. If we want to see more results, then we can specify that in trace tag of configuration file by using the requestLimit property. It shows as many trace results specified in that property. Otherwise we can clear the visible results and see the next ones. We also have the option of dumping the trace results in System.Diagnostics by specifiying writeToDiagnosticsTrace property to true.
3. Sys.Debug:
This option had been very useful from VS2005. Even in VS2008 it is used for conditional breaking and other options. Microsoft AJAX library provides Sys.Debug class for debugging client applications.
Important methods in Sys.Debug:
a) Sys.Debug.assert(<condition>, message, displayCaller)
This method checks for a condition and if the condition is false, displays a message and prompts the user to break into debugger.
Ex:
function Btn_click() { var a = 10;
Sys.Debug.assert(a > 9, "Value greater than 9", true);
}
When the assertion fails, it prompts for debugging. If the displayCaller is specified as true it displays the caller function also in the prompt. If debugging is selected it shows enters into debug mode with a break. To start debugging, press F11. At this time the scripts can be observed in solution explorer.
b) Sys.Debug.traceDump(object, name)
Dumps an object to the debugger console and to the TraceConsole text area element, if available.
Ex:
var elmt = getElementById(“DataList1”);
Sys.Debug.traceDump(c,"This is the dump");
c) Sys.Debug.fail(message)
This statement breaks wherever it is written. The given message is displayed in the debugger‟s output window.
This was much useful in VS2005, but in VS2008 there is no need of this statement as we can directly put breakpoints at client-side scripts.
Ex: Sys.Debug.fail("This is breakpoint");
But the scripts do no appear in solution explorer window. If needed, they can be viewed from DebugàWindowsàScriptExplorer
d) Sys.Debug.trace(text)
Appends the supplied textline to the debugger console and to the TraceConsole text area element, if available.
Ex: Sys.Debug.trace("This is debugging");
Tools used for debugging:
Fiddler: This is a tool recommended by Microsoft. It is Web debugging proxy which logs all the traffic between the client and the server. It allows us to set breakpoints and inspect data transfer.
Nikhil‟s Web Development helper: It is a plugin for Internet Explorer. Helps in inspecting and debugging the web apps.
Firebug: It enables you to stop through client script and examine HTML DOM elements. It also provides a script console, a command line and other tools.
Venkman JavaScript Debugger:
It provides a JavaScript debugging environment that includes a source code browser and other features. Useful for Firefox and Netscape browsers.
Web Developer extension for Firefox: It enables us to inspect the DOM and CSS styles.
ASP.NET AJAX Control Toolkit:
· Used for easily enhancing existing websites (or creating new ones)
· There are over 60+ AJAX-enabled components
· JavaScript skills are not required for using this toolkit
· Provides a new design experience in VS2008, whereas it was drag and drop in VS2005
· It can be easily deployed to website‟s bin directory
· The included source code allows customization and /or fixes by users
Installing toolkit:
Features:
· Cross-browser support –This toolkit support all the browsers that ASP.NET AJAX supports like IE 6/7/8, Firefox, Safari and Opera.
· Plays nicely with other AJAX frameworks
· Includes extenders, controls and behaviors
· The code and other official releases are available at http://www.codeplex.com/
Some important toolkit controls:
· AutoComplete Extender (most useful one)
· ConfirmButton Extender
· ValidatorCallout Extender
· DropShadow Extender
· TextBoxWatermark
· TabControl
AutoComplete Extender
This extender gives prompts to the user regarding the word being typed in the textbox. The prompt strings can be taken by using a Web Service method. The Web service source can be any service from the net or any xml file. The service method is specified in the ServiceMethod property. If a Web service is used, the wsdl path should be specified in the Service path. In our example we use an xml file which should be given in the method by using mappath method.
Normally in ASP.NET programs, if we use a Web service, we use [WebMethod] attribute to indicate that it is a Web service method. Such methods are SOAP-enabled and work fine with ASP.NET applications. But if AJAX is used, it cannot work with SOAP. AJAX can communicate only through JSON serialization. So we have to use [ScriptMethod] attribute if we are using AJAX.
For our demo we follow the below steps:
1. Design the form by placing a label, textbox and search button.
2. Now we‟ll add the AutoComplete Extender to the textbox where the user will type the description of a product for searching it. To do this, click the smart tag of the textbox and select AutoComplete Extender. Now some more properties related to this extender will be added to the textbox properties. We have to specify the ServiceMethod property by giving any method name. Then we can click the Add AutoComplete page method link which appears at the bottom in the events section of that textbox. Once that link is clicked a page method will be created in the code-behind with all the necessary attributes and with the specified name.
Note: Though this method appears in the code-behind file, it is not a part of the page.
3. In this method we have to write our code of retrieving the description from xml file to prompt the user.
For this we use LinqtoXml and write the below code:
using System.Xml.Linq; [System.Web.Services.WebMethodAttribute(),
System.Web.Script.Services.ScriptMethodAttribute()]
public static string[] PromptItemDesc(string prefixText, int count,
string contextKey)
{
XElement el = XElement.Load(HttpContext.Current.Request.MapPath("Items.xml"));
var x = from n in el.Elements("Item")
where n.Element("Description").Value.ToUpper(). Contains(prefixText.ToUpper())
select n.Element("Description").Value;
return x.ToArray<string>();
}
This method loads the xml file and reads the description of all the elements depending upon the given condition(if the string being typed exists anywhere in description of an item). It returns all the descriptions satisfying the condition in the form of an array of strings which are displayed over the textbox as the user starts typing.
We have specified the MinimumPrefixLength as 1 which means the prompts are displayed as soon as the first character is entered in the textbox by the user.
4. If the user selects any description or types his own and clicks on search results should be displayed in a GridView. For this we place a GridView in a panel below the textbox. To display the results we write the following code in Search button click event.
XElement el = XElement.Load(MapPath("Items.xml")); var x = from n in el.Elements("Item")
where n.Element("Description").Value.ToUpper(). Contains(TextBox1.Text.ToUpper())
select new
{
Description=n.Element("Description").Value, Feature = n.Element("Feature").Value, Vendor = n.Element("Seller").Value,
Price = n.Element("Price").Value
};
<configuration> <system.web>
<trace enabled="true" pageOutput="true" />
If trace is set to true, it means that a trace is generated and if the pageOutput is true the tracing results will be appended to the page. But this does not work for aysnchronous requests i.e., ASP.NET AJAX does not show trace results at the end of the page ( though trace is generated in this case also).
Note: The trace can be observed in all browsers.
We can view the complete trace using trace utility.
Type trace.axd after the url of the application. Suppose the path is :
http://localhost/myajaxapp/default.aspx
then trace can be observed by typing
http://localhost/ajaxsports/default.aspx/trace.axd
By default there is a limit of 10 results for the results generated by trace. If we want to see more results, then we can specify that in trace tag of configuration file by using the requestLimit property. It shows as many trace results specified in that property. Otherwise we can clear the visible results and see the next ones. We also have the option of dumping the trace results in System.Diagnostics by specifiying writeToDiagnosticsTrace property to true.
3. Sys.Debug:
This option had been very useful from VS2005. Even in VS2008 it is used for conditional breaking and other options. Microsoft AJAX library provides Sys.Debug class for debugging client applications.
Important methods in Sys.Debug:
a) Sys.Debug.assert(<condition>, message, displayCaller)
This method checks for a condition and if the condition is false, displays a message and prompts the user to break into debugger.
Ex:
function Btn_click() { var a = 10;
Sys.Debug.assert(a > 9, "Value greater than 9", true);
}
When the assertion fails, it prompts for debugging. If the displayCaller is specified as true it displays the caller function also in the prompt. If debugging is selected it shows enters into debug mode with a break. To start debugging, press F11. At this time the scripts can be observed in solution explorer.
b) Sys.Debug.traceDump(object, name)
Dumps an object to the debugger console and to the TraceConsole text area element, if available.
Ex:
var elmt = getElementById(“DataList1”);
Sys.Debug.traceDump(c,"This is the dump");
c) Sys.Debug.fail(message)
This statement breaks wherever it is written. The given message is displayed in the debugger‟s output window.
This was much useful in VS2005, but in VS2008 there is no need of this statement as we can directly put breakpoints at client-side scripts.
Ex: Sys.Debug.fail("This is breakpoint");
But the scripts do no appear in solution explorer window. If needed, they can be viewed from DebugàWindowsàScriptExplorer
d) Sys.Debug.trace(text)
Appends the supplied textline to the debugger console and to the TraceConsole text area element, if available.
Ex: Sys.Debug.trace("This is debugging");
Tools used for debugging:
Fiddler: This is a tool recommended by Microsoft. It is Web debugging proxy which logs all the traffic between the client and the server. It allows us to set breakpoints and inspect data transfer.
Nikhil‟s Web Development helper: It is a plugin for Internet Explorer. Helps in inspecting and debugging the web apps.
Firebug: It enables you to stop through client script and examine HTML DOM elements. It also provides a script console, a command line and other tools.
Venkman JavaScript Debugger:
It provides a JavaScript debugging environment that includes a source code browser and other features. Useful for Firefox and Netscape browsers.
Web Developer extension for Firefox: It enables us to inspect the DOM and CSS styles.
ASP.NET AJAX Control Toolkit:
· Used for easily enhancing existing websites (or creating new ones)
· There are over 60+ AJAX-enabled components
· JavaScript skills are not required for using this toolkit
· Provides a new design experience in VS2008, whereas it was drag and drop in VS2005
· It can be easily deployed to website‟s bin directory
· The included source code allows customization and /or fixes by users
Installing toolkit:
- Download the toolkit from Codeplex or asp.net websites (with or without source)
- Extract it
- Copy .dll file from SampleWebsite‟s bin folder to some binaries or other folder
- Open any website, right click on toolbox and choose items – From there select the copied .dll and observe that all related controls are selected
Features:
· Cross-browser support –This toolkit support all the browsers that ASP.NET AJAX supports like IE 6/7/8, Firefox, Safari and Opera.
· Plays nicely with other AJAX frameworks
· Includes extenders, controls and behaviors
· The code and other official releases are available at http://www.codeplex.com/
Some important toolkit controls:
· AutoComplete Extender (most useful one)
· ConfirmButton Extender
· ValidatorCallout Extender
· DropShadow Extender
· TextBoxWatermark
· TabControl
AutoComplete Extender
This extender gives prompts to the user regarding the word being typed in the textbox. The prompt strings can be taken by using a Web Service method. The Web service source can be any service from the net or any xml file. The service method is specified in the ServiceMethod property. If a Web service is used, the wsdl path should be specified in the Service path. In our example we use an xml file which should be given in the method by using mappath method.
Normally in ASP.NET programs, if we use a Web service, we use [WebMethod] attribute to indicate that it is a Web service method. Such methods are SOAP-enabled and work fine with ASP.NET applications. But if AJAX is used, it cannot work with SOAP. AJAX can communicate only through JSON serialization. So we have to use [ScriptMethod] attribute if we are using AJAX.
For our demo we follow the below steps:
1. Design the form by placing a label, textbox and search button.
2. Now we‟ll add the AutoComplete Extender to the textbox where the user will type the description of a product for searching it. To do this, click the smart tag of the textbox and select AutoComplete Extender. Now some more properties related to this extender will be added to the textbox properties. We have to specify the ServiceMethod property by giving any method name. Then we can click the Add AutoComplete page method link which appears at the bottom in the events section of that textbox. Once that link is clicked a page method will be created in the code-behind with all the necessary attributes and with the specified name.
Note: Though this method appears in the code-behind file, it is not a part of the page.
3. In this method we have to write our code of retrieving the description from xml file to prompt the user.
For this we use LinqtoXml and write the below code:
using System.Xml.Linq; [System.Web.Services.WebMethodAttribute(),
System.Web.Script.Services.ScriptMethodAttribute()]
public static string[] PromptItemDesc(string prefixText, int count,
string contextKey)
{
XElement el = XElement.Load(HttpContext.Current.Request.MapPath("Items.xml"));
var x = from n in el.Elements("Item")
where n.Element("Description").Value.ToUpper(). Contains(prefixText.ToUpper())
select n.Element("Description").Value;
return x.ToArray<string>();
}
This method loads the xml file and reads the description of all the elements depending upon the given condition(if the string being typed exists anywhere in description of an item). It returns all the descriptions satisfying the condition in the form of an array of strings which are displayed over the textbox as the user starts typing.
We have specified the MinimumPrefixLength as 1 which means the prompts are displayed as soon as the first character is entered in the textbox by the user.
4. If the user selects any description or types his own and clicks on search results should be displayed in a GridView. For this we place a GridView in a panel below the textbox. To display the results we write the following code in Search button click event.
XElement el = XElement.Load(MapPath("Items.xml")); var x = from n in el.Elements("Item")
where n.Element("Description").Value.ToUpper(). Contains(TextBox1.Text.ToUpper())
select new
{
Description=n.Element("Description").Value, Feature = n.Element("Feature").Value, Vendor = n.Element("Seller").Value,
Price = n.Element("Price").Value
};
GridView1.DataSource = x; GridView1.DataBind();
When this button is clicked the results will be displayed in the GridView.
ConfirmButton Extender
This extender is used to display a message box kind of prompt for asking the user to proceed with an action or not. The prompt text to be displayed is given in ConfirmText property.
TextBox Watermark Extender
This extender is used to display some watermark text inside a textbox, so that the user can be informed what kind of text he has to enter. As soon as the user clicks inside the text box to enter some text, it disappears. It appears in the textbox only when left blank without any text.
As shown above the textbox is having a watermark called “Description”. This text can be given through WatermarkText property. The color and font of the text can be adjusted through a css file.
DropShadow Extender
This extender is used to show a little shadow beside a control so that it appears a little raised from the back surface. Though this extender works with other controls also, it is preferable to use it with a panel control.
UpdatePanelAnimation Extender
When this button is clicked the results will be displayed in the GridView.
ConfirmButton Extender
This extender is used to display a message box kind of prompt for asking the user to proceed with an action or not. The prompt text to be displayed is given in ConfirmText property.
TextBox Watermark Extender
This extender is used to display some watermark text inside a textbox, so that the user can be informed what kind of text he has to enter. As soon as the user clicks inside the text box to enter some text, it disappears. It appears in the textbox only when left blank without any text.
As shown above the textbox is having a watermark called “Description”. This text can be given through WatermarkText property. The color and font of the text can be adjusted through a css file.
DropShadow Extender
This extender is used to show a little shadow beside a control so that it appears a little raised from the back surface. Though this extender works with other controls also, it is preferable to use it with a panel control.
UpdatePanelAnimation Extender
UpdatePanelAnimation Extender allows us to create animations for an UpdatePanel using the methods OnUpdated() and OnUpdating(). OnUpdating() is a method which is invoked when the updation is taking place in an UpdatePanel. OnUpdated() is invoked after the updation has taken place.
Demo:
In this program we take an xml file called books.xml as our data source. The form design is as given below:
These three controls are inside UpdatePanel1. After placing these controls we add UpdatePanelAnimationExtender.
<cc1:UpdatePanelAnimationExtender ID="upae" BehaviorID="animation" runat="server" Enabled="True" TargetControlID="UpdatePanel1">
<Animations> <OnUpdating>
<Parallel duration="0">
<FadeOut minimumOpacity=".5" />
<EnableAction AnimationTarget="BtnSearch" Enabled="false" /> <EnableAction AnimationTarget="TextBox1" Enabled="false" /> <ScriptAction Script="onUpdating();"/>
</Parallel> </OnUpdating>
<OnUpdated>
<Parallel duration="0">
<FadeIn minimumOpacity="1" />
<EnableAction AnimationTarget="Btnsearch" Enabled="true" /> <EnableAction AnimationTarget="TextBox1" Enabled="true" />
<ScriptAction Script="onUpdated();"></ScriptAction> </Parallel>
</OnUpdated> </Animations>
</cc1:UpdatePanelAnimationExtender>
Since TargetControlId is UpdatePanel1, this extender will call the OnUpdating() and OnUpdated() methods while UpdatePanel1 is updating and updated respectively.
The JavaScript code for the given two methods is as follows:
function onUpdating() {
var updateProgressDiv = $get('updateProgressDiv'); updateProgressDiv.style.display='block';
var gridview = $get('<%= this.GridView1.ClientID %>');
var gridviewbounds = Sys.UI.DocumentElement.getBounds(gridview); var updateProgressDivBounds =
Sys.UI.DocumentElement.getBounds(updateProgressDiv); var x = gridviewbounds.x + Math.round(gridviewbounds.Width / 2)
- Math.round(updateProgressDivBounds.Width / 2); var y = gridviewbounds.y + Math.round(gridviewbounds.Height / 2)
- Math.round(updateProgressDivBounds.Height / 2); Sys.UI.DOMElement.SetLocation(updateProgressDiv, x, y);
}
function onUpdated() {
var updateProgressDiv = $get('updateProgressDiv'); updateProgressDiv.style.display = 'none';
}
Here updateProgressDiv is <div> where the gif image showing the updating status is placed. This is not visible on the screen initially (because it‟s display is made none), but when the updation is taking place it appears just during that time because of the display is made to „block‟ in the OnUpdating() function.
<div id="updateProgressDiv" runat="server"
style="display:none; height:40px; width:1000px; text-align=center;">
<img alt="" src="loading.gif" />
</div>
The button click code for fetching the data from the data source is given below:
protected void BtnSearch_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(5000);
XElement ele = XElement.Load(MapPath("books.xml")); var x = from el in ele.Elements("book")
where el.Element("author").Value.ToUpper(). Contains(TextBox1.Text.ToUpper())
select new
{
author = el.Element("author").Value, title = el.Element("title").Value, genre = el.Element("genre").Value, price = el.Element("price").Value,
description = el.Element("description").Value
};
Demo:
In this program we take an xml file called books.xml as our data source. The form design is as given below:
These three controls are inside UpdatePanel1. After placing these controls we add UpdatePanelAnimationExtender.
<cc1:UpdatePanelAnimationExtender ID="upae" BehaviorID="animation" runat="server" Enabled="True" TargetControlID="UpdatePanel1">
<Animations> <OnUpdating>
<Parallel duration="0">
<FadeOut minimumOpacity=".5" />
<EnableAction AnimationTarget="BtnSearch" Enabled="false" /> <EnableAction AnimationTarget="TextBox1" Enabled="false" /> <ScriptAction Script="onUpdating();"/>
</Parallel> </OnUpdating>
<OnUpdated>
<Parallel duration="0">
<FadeIn minimumOpacity="1" />
<EnableAction AnimationTarget="Btnsearch" Enabled="true" /> <EnableAction AnimationTarget="TextBox1" Enabled="true" />
<ScriptAction Script="onUpdated();"></ScriptAction> </Parallel>
</OnUpdated> </Animations>
</cc1:UpdatePanelAnimationExtender>
Since TargetControlId is UpdatePanel1, this extender will call the OnUpdating() and OnUpdated() methods while UpdatePanel1 is updating and updated respectively.
The JavaScript code for the given two methods is as follows:
function onUpdating() {
var updateProgressDiv = $get('updateProgressDiv'); updateProgressDiv.style.display='block';
var gridview = $get('<%= this.GridView1.ClientID %>');
var gridviewbounds = Sys.UI.DocumentElement.getBounds(gridview); var updateProgressDivBounds =
Sys.UI.DocumentElement.getBounds(updateProgressDiv); var x = gridviewbounds.x + Math.round(gridviewbounds.Width / 2)
- Math.round(updateProgressDivBounds.Width / 2); var y = gridviewbounds.y + Math.round(gridviewbounds.Height / 2)
- Math.round(updateProgressDivBounds.Height / 2); Sys.UI.DOMElement.SetLocation(updateProgressDiv, x, y);
}
function onUpdated() {
var updateProgressDiv = $get('updateProgressDiv'); updateProgressDiv.style.display = 'none';
}
Here updateProgressDiv is <div> where the gif image showing the updating status is placed. This is not visible on the screen initially (because it‟s display is made none), but when the updation is taking place it appears just during that time because of the display is made to „block‟ in the OnUpdating() function.
<div id="updateProgressDiv" runat="server"
style="display:none; height:40px; width:1000px; text-align=center;">
<img alt="" src="loading.gif" />
</div>
The button click code for fetching the data from the data source is given below:
protected void BtnSearch_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(5000);
XElement ele = XElement.Load(MapPath("books.xml")); var x = from el in ele.Elements("book")
where el.Element("author").Value.ToUpper(). Contains(TextBox1.Text.ToUpper())
select new
{
author = el.Element("author").Value, title = el.Element("title").Value, genre = el.Element("genre").Value, price = el.Element("price").Value,
description = el.Element("description").Value
};
GridView1.DataSource = x; GridView1.DataBind();
}
Screenshot while updating :
Here the background is disabled and only the updating progress image is active. Screenshot after updation:
So, in short, for the above demo the following steps should be observed:
1. Create UpdatePanel and place a GridView with all functionality like editing, paging, sorting etc.
2. Add UpdatePanel animation extender for the created UpdatePanel.
3. Go to source view and as part of Update Panel animation extender create the animations using <Animations>
4. Create a new div tag with some ID and place the updating image in it.
5. Write the code in OnUpdated() and OnUpdating() functions.
ModalPopUpExtender
With ModalPopUpExtender we can display dialog boxes like desktops till we close the window. No output or interaction will be provided with this control. ModalPopUpExtender can be used with any control but for displaying multiple content use panel and display the result.
The main properties to set in this control are:
TargetControlID- The control whose click event causes the popup PopUpControlId-The control which pops up
PopupDragHandleControlID–The control which on moving moves the position of the popped up control
BackgroundCssClass-CSS class for the background of popup control
Accordion
This is the AJAX control which provides good presentation by enabling the user to expand and collapse the panes (different sections in the control). This mostly used to save space on the screen as the panes are collapsible. Only one pane can be opened at a time which gives a good and neat look. An Accordion can consist of several Accordion Panes. Panes is a collection which contains AccordionPanes. We can put static as well as dynamic content in these panes. We can have Accordion without panes also.
The Accordion consists of a ContentTemplate and a HeaderTemplate. The Contents in the Header template are displayed over the top header part and the contents in the content template are displayed when the pane is expanded.
Here the dark blue colored part is the header of each pane and the light blue part where the details are displayed is the content part. We can see the content part of only one pane at a time.
The best thing about Accordion is that we can do databinding to it. Like in ItemTemplate of other databinding controls we can write Eval values directly in this control.
The main properties to be set here are ContentCssClass and HeaderCssClass without which the Accordion loses its look.
Demo: Accordion without Panes
In this demo we display data from an xml data source in the Accordion when a button is clicked. The records are displayed in the Accordion as panes, though we do not explicitly create them.
First we take a button and an accordion. We retrieve the records from an xml file called items.xml in the button click event and then bind them to the accordion. The speciality of accordion is that we can directly display the binded values using Evals in it, just as we can do in ItemTemplate of GridView.
The code in button click event is given below:
XElement el=XElement.Load(MapPath("~/Items.xml")); var res = from x in el.Elements("Item")
select new
{
Description = x.Element("Description").Value, Feature = x.Element("Feature").Value,
Seller = x.Element("Seller").Value, Price = x.Element("Price").Value, Image = x.Element("Image").Value,
}; Accordion1.DataSource = res; Accordion1.DataBind();
After binding the data we have to display these fields in accordion. For that in source code we use Evals for the purporse.
<cc1:Accordion ID="Accordion1" runat="server" FadeTransitions="true" RequireOpenedPane="false" HeaderCssClass="accordionHeader" ContentCssClass="accordionContent">
<HeaderTemplate>
<%# Eval("Description") %> </HeaderTemplate>
<ContentTemplate>
<asp:ImageButton ID="btnImg" runat="server" ImageUrl='<%#Eval("Image") %>' Height="100" OnClick="btnImg_Click" />
<br />
<asp:Label id="lbl1" runat="server" Text="Features :"
style="font-weight:bold; color:Blue" /> <%# Eval("Feature") %>
<br />
<asp:Label id="lbl2" runat="server" Text="Vendor:" style="font-weight:bold; color:Blue" />
<%# Eval("Seller") %> <br /
<asp:Label id="lb3" runat="server" Text="Price:"
style="font-weight:bold; color:Blue"/> <%# Eval("Price") %>
<br /> </ContentTemplate>
</cc1:Accordion>
For accordion we have set properties like HeaderCssClass, ContentCssClass, RequireOpenPane and FadeTransitions. The FadeTransitions property when set to true shows a fading effect when the panes are closing and opening. If RequireOpenPane property is set to false, then it is not necessary that a pane should be open. We can close all the panes if needed.
This program displays all the records in the xml file in the Accordion. As many panes will be displayed as there are records. The output screen will be as shown above in Accordion explanation.
SlideShowExtender:
This extender displays images in a slideshow form. It provides different properties like autoplay, looping. We can assign different buttons for play, stop, next slide, previous slide etc.
Steps to use a SlideShowExtender:
1. Place Image control and provide required CSS to it
2. Create some buttons for Next, Previous and Play.
3. Select Image and add SlideShowExtender. Generate page web method from smart tag
4. In WebMethod write code to provide source of images. This WebMethod expects an array of slides class which is present in AJAXControlToolkit namespace. We can fill the slide array with our numbers i.e. in size using the slide constructor and also with its methods.
Ex: AjaxControlToolkit.Slide[] slides = new AjaxControlToolkit.Slide[8];
In the above statement it is declared that the number of slides will be 8. To provide the images we write something like this
slides[0] = new AjaxControlToolkit.Slide("Calvin and Hobbes.jpg", "Calvin and Hobbes","Calvin on adventure");
Slides[0] represents the first slide image. The parameters to be passed are: (i)The path of the image (ii)The name of the image (iii) The description of the image. In this way we can add as many images as needed.
Demo- SlideShowExtender with locally stored images
Here we design our form with an image control and three buttons for previous, play and next. Here it should be noted that there is no stop button because the play button itself acts as stop button when it is clicked. That is why a property called Stop Button Text is to be specified which is the text to be displayed on the button when the play button is clicked. In our program we have given the text as “Stop”.
After this, add the SlideShowExtender to the image control from the smart tag and then add the page web method and name it GetSlides(). The code for the method is given below:
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static
AjaxControlToolkit.Slide[] GetSlides()
{
AjaxControlToolkit.Slide[] slides = new AjaxControlToolkit.Slide[6];
slides[0] =
new AjaxControlToolkit.Slide("images/Calvin and Hobbes.jpg",
"Calvin and Hobbes","Calvin on adventure");
slides[1] =
new AjaxControlToolkit.Slide("images/cowboys.jpg", "Cowboys",
"Cowboys at dusk");
slides[2] =
new AjaxControlToolkit.Slide("images/Dolphin.jpg", "Dolphin",
"A friendly dolphin under water");
slides[3] =
new AjaxControlToolkit.Slide("images/dumbo.jpg", "Dumbo",
"Dumbo - The baby elephant");
slides[4] =
new AjaxControlToolkit.Slide("images/Golf ball.jpg", "Golf
Ball", "Golf ball at the hole");
slides[5] =
new AjaxControlToolkit.Slide("images/GreenApples.jpg", "Green
Apples", "");
slides[6] =
new AjaxControlToolkit.Slide("images/Maple Tree.jpg", "Maple
Tree", "Maple tree in spring");
return slides;
}
This web service method name should be specified for SlideShowExtender in its SlideShowServiceMethod property. The source code for this extender is given below:
<cc1:SlideShowExtender ID="Image1_SlideShowExtender" runat="server" Enabled="True" SlideShowServiceMethod="GetSlides" TargetControlID="Image1"
PlayButtonID="btnPlay" PreviousButtonID="btnPrev" StopButtonText="Stop" NextButtonID="btnNext" ImageTitleLabelID="lblTitle" ImageDescriptionLabelID="lblDesc" >
</cc1:SlideShowExtender>
For this extender if the AutoPlay property is set to true, then the slides will start changing automatically without the need to click the Play button. As shown in the screen shot below the slides will be displayed in the Image control.
Demo2 – SlideShow using Flickr API
In this demo we‟ll see a live example of showing the slideshow using images from Flickr using its API. For this we need to register in Flickr site for an API key and its secret code. After gettting the key we can proceed to creating our slideshow.
The steps will be same as we do for images stored locally. Only there will be a slight change in the code.
First we‟ll design the form just like in the earlier demo with an image control and three buttons for Previous, Play and Next. Here we‟ll provide an additional text box and a button. The purpose of the textbox is to give the keyword for searching the images.
After entering the keyword we‟ll press the button to get the images.
We provide our api key in configuration settings.
(In root web.config file)
<appSettings>
<add key="flickrAPI" value="http://flickr.com/services/rest/?api_key=abcde12345678901abcdefgh"/> </appSettings>
Since we have to pass the keyword as parameter to our page method, we use a context key for the purpose.
<script language="javascript" type="text/javascript">
function Button1_onclick() {
var x = document.getElementById("Text1").value;
$find("Image1_SlideShowExtender").set_contextKey(x);
}
</script>
Here Text1 is our html textbox and Image1_SlideShowExtender is the ID of our SlideShowExtender.
The code in page method is written as follows:
[System.Web.Services.WebMethod] [System.Web.Script.Services.ScriptMethod]
public static AjaxControlToolkit.Slide[] GetSlides(string contextKey)
{
string keyword = contextKey;
XmlDataSource xmlData = new XmlDataSource(); xmlData.DataFile =
ConfigurationManager.AppSettings["flickrAPI"].ToString() + "&method=flickr.photos.search&text=" +
keyword + "&accuracy=1&safe_search=1&per_page=9&privacy_filter=1
&content_type=1&sort=relevance"; XmlDocument xmlDoc = xmlData.GetXmlDocument();
XmlNodeList xmlNodes = xmlDoc.SelectNodes("rsp/photos/photo"); AjaxControlToolkit.Slide[] slides = new AjaxControlToolkit.Slide[xmlNodes.Count];
for (int i = 0; i < xmlNodes.Count; i++)
{
slides[i] = new AjaxControlToolkit.Slide("http://farm" + xmlNodes[i].Attributes["farm"].Value + ".static.flickr.com/" + xmlNodes[i].Attributes["server"].Value + "/" + xmlNodes[i].Attributes["id"].Value + "_" + xmlNodes[i].Attributes["secret"].Value + "_m.jpg", xmlNodes[i].Attributes["title"].Value, "Photo-" + (i + 1).ToString() + ":");
}
return (slides);
}
This method takes the keyword we provided as contextKey and assigns it to the variable keyword. We get the data from Flickr in xml form by using the method flickr.photos.search and giving the required attributes to it, like the keyword, accuracy, safe search, number of images to be retrieved etc. The fetched data is displayed in the form of slideshow with images, title, photo name etc.
Communicationg with Web Services and WCF
Communication with Web Services in AJAX is purely client-centric development because the calls go to the services from client without the involvement of server.
Calling Web Services using MS-AJAX
- Microsoft AJAX technologies can pass data to and from Web Services
(This requires that the [ScriptService] attribute be applied to Web Service classes)
- AJAX‟s big win is invoking server code from the client page
- Web Services can be called using several different techniques:
AutoCompleteExtender and other controls
JavaScript
XML (This is in declarative method – but used very rarely)
Communication with Web Services in AJAX is purely client-centric development because the calls go to the services from client without the involvement of server.
Calling Web Services using MS-AJAX
- Microsoft AJAX technologies can pass data to and from Web Services
(This requires that the [ScriptService] attribute be applied to Web Service classes)
- AJAX‟s big win is invoking server code from the client page
- Web Services can be called using several different techniques:
}
Screenshot while updating :
Here the background is disabled and only the updating progress image is active. Screenshot after updation:
So, in short, for the above demo the following steps should be observed:
1. Create UpdatePanel and place a GridView with all functionality like editing, paging, sorting etc.
2. Add UpdatePanel animation extender for the created UpdatePanel.
3. Go to source view and as part of Update Panel animation extender create the animations using <Animations>
4. Create a new div tag with some ID and place the updating image in it.
5. Write the code in OnUpdated() and OnUpdating() functions.
ModalPopUpExtender
With ModalPopUpExtender we can display dialog boxes like desktops till we close the window. No output or interaction will be provided with this control. ModalPopUpExtender can be used with any control but for displaying multiple content use panel and display the result.
The main properties to set in this control are:
TargetControlID- The control whose click event causes the popup PopUpControlId-The control which pops up
PopupDragHandleControlID–The control which on moving moves the position of the popped up control
BackgroundCssClass-CSS class for the background of popup control
Accordion
This is the AJAX control which provides good presentation by enabling the user to expand and collapse the panes (different sections in the control). This mostly used to save space on the screen as the panes are collapsible. Only one pane can be opened at a time which gives a good and neat look. An Accordion can consist of several Accordion Panes. Panes is a collection which contains AccordionPanes. We can put static as well as dynamic content in these panes. We can have Accordion without panes also.
The Accordion consists of a ContentTemplate and a HeaderTemplate. The Contents in the Header template are displayed over the top header part and the contents in the content template are displayed when the pane is expanded.
Here the dark blue colored part is the header of each pane and the light blue part where the details are displayed is the content part. We can see the content part of only one pane at a time.
The best thing about Accordion is that we can do databinding to it. Like in ItemTemplate of other databinding controls we can write Eval values directly in this control.
The main properties to be set here are ContentCssClass and HeaderCssClass without which the Accordion loses its look.
Demo: Accordion without Panes
In this demo we display data from an xml data source in the Accordion when a button is clicked. The records are displayed in the Accordion as panes, though we do not explicitly create them.
First we take a button and an accordion. We retrieve the records from an xml file called items.xml in the button click event and then bind them to the accordion. The speciality of accordion is that we can directly display the binded values using Evals in it, just as we can do in ItemTemplate of GridView.
The code in button click event is given below:
XElement el=XElement.Load(MapPath("~/Items.xml")); var res = from x in el.Elements("Item")
select new
{
Description = x.Element("Description").Value, Feature = x.Element("Feature").Value,
Seller = x.Element("Seller").Value, Price = x.Element("Price").Value, Image = x.Element("Image").Value,
}; Accordion1.DataSource = res; Accordion1.DataBind();
After binding the data we have to display these fields in accordion. For that in source code we use Evals for the purporse.
<cc1:Accordion ID="Accordion1" runat="server" FadeTransitions="true" RequireOpenedPane="false" HeaderCssClass="accordionHeader" ContentCssClass="accordionContent">
<HeaderTemplate>
<%# Eval("Description") %> </HeaderTemplate>
<ContentTemplate>
<asp:ImageButton ID="btnImg" runat="server" ImageUrl='<%#Eval("Image") %>' Height="100" OnClick="btnImg_Click" />
<br />
<asp:Label id="lbl1" runat="server" Text="Features :"
style="font-weight:bold; color:Blue" /> <%# Eval("Feature") %>
<br />
<asp:Label id="lbl2" runat="server" Text="Vendor:" style="font-weight:bold; color:Blue" />
<%# Eval("Seller") %> <br /
<asp:Label id="lb3" runat="server" Text="Price:"
style="font-weight:bold; color:Blue"/> <%# Eval("Price") %>
<br /> </ContentTemplate>
</cc1:Accordion>
For accordion we have set properties like HeaderCssClass, ContentCssClass, RequireOpenPane and FadeTransitions. The FadeTransitions property when set to true shows a fading effect when the panes are closing and opening. If RequireOpenPane property is set to false, then it is not necessary that a pane should be open. We can close all the panes if needed.
This program displays all the records in the xml file in the Accordion. As many panes will be displayed as there are records. The output screen will be as shown above in Accordion explanation.
SlideShowExtender:
This extender displays images in a slideshow form. It provides different properties like autoplay, looping. We can assign different buttons for play, stop, next slide, previous slide etc.
Steps to use a SlideShowExtender:
1. Place Image control and provide required CSS to it
2. Create some buttons for Next, Previous and Play.
3. Select Image and add SlideShowExtender. Generate page web method from smart tag
4. In WebMethod write code to provide source of images. This WebMethod expects an array of slides class which is present in AJAXControlToolkit namespace. We can fill the slide array with our numbers i.e. in size using the slide constructor and also with its methods.
Ex: AjaxControlToolkit.Slide[] slides = new AjaxControlToolkit.Slide[8];
In the above statement it is declared that the number of slides will be 8. To provide the images we write something like this
slides[0] = new AjaxControlToolkit.Slide("Calvin and Hobbes.jpg", "Calvin and Hobbes","Calvin on adventure");
Slides[0] represents the first slide image. The parameters to be passed are: (i)The path of the image (ii)The name of the image (iii) The description of the image. In this way we can add as many images as needed.
Demo- SlideShowExtender with locally stored images
Here we design our form with an image control and three buttons for previous, play and next. Here it should be noted that there is no stop button because the play button itself acts as stop button when it is clicked. That is why a property called Stop Button Text is to be specified which is the text to be displayed on the button when the play button is clicked. In our program we have given the text as “Stop”.
After this, add the SlideShowExtender to the image control from the smart tag and then add the page web method and name it GetSlides(). The code for the method is given below:
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static
AjaxControlToolkit.Slide[] GetSlides()
{
AjaxControlToolkit.Slide[] slides = new AjaxControlToolkit.Slide[6];
slides[0] =
new AjaxControlToolkit.Slide("images/Calvin and Hobbes.jpg",
"Calvin and Hobbes","Calvin on adventure");
slides[1] =
new AjaxControlToolkit.Slide("images/cowboys.jpg", "Cowboys",
"Cowboys at dusk");
slides[2] =
new AjaxControlToolkit.Slide("images/Dolphin.jpg", "Dolphin",
"A friendly dolphin under water");
slides[3] =
new AjaxControlToolkit.Slide("images/dumbo.jpg", "Dumbo",
"Dumbo - The baby elephant");
slides[4] =
new AjaxControlToolkit.Slide("images/Golf ball.jpg", "Golf
Ball", "Golf ball at the hole");
slides[5] =
new AjaxControlToolkit.Slide("images/GreenApples.jpg", "Green
Apples", "");
slides[6] =
new AjaxControlToolkit.Slide("images/Maple Tree.jpg", "Maple
Tree", "Maple tree in spring");
return slides;
}
This web service method name should be specified for SlideShowExtender in its SlideShowServiceMethod property. The source code for this extender is given below:
<cc1:SlideShowExtender ID="Image1_SlideShowExtender" runat="server" Enabled="True" SlideShowServiceMethod="GetSlides" TargetControlID="Image1"
PlayButtonID="btnPlay" PreviousButtonID="btnPrev" StopButtonText="Stop" NextButtonID="btnNext" ImageTitleLabelID="lblTitle" ImageDescriptionLabelID="lblDesc" >
</cc1:SlideShowExtender>
For this extender if the AutoPlay property is set to true, then the slides will start changing automatically without the need to click the Play button. As shown in the screen shot below the slides will be displayed in the Image control.
Demo2 – SlideShow using Flickr API
In this demo we‟ll see a live example of showing the slideshow using images from Flickr using its API. For this we need to register in Flickr site for an API key and its secret code. After gettting the key we can proceed to creating our slideshow.
The steps will be same as we do for images stored locally. Only there will be a slight change in the code.
First we‟ll design the form just like in the earlier demo with an image control and three buttons for Previous, Play and Next. Here we‟ll provide an additional text box and a button. The purpose of the textbox is to give the keyword for searching the images.
After entering the keyword we‟ll press the button to get the images.
We provide our api key in configuration settings.
(In root web.config file)
<appSettings>
<add key="flickrAPI" value="http://flickr.com/services/rest/?api_key=abcde12345678901abcdefgh"/> </appSettings>
Since we have to pass the keyword as parameter to our page method, we use a context key for the purpose.
<script language="javascript" type="text/javascript">
function Button1_onclick() {
var x = document.getElementById("Text1").value;
$find("Image1_SlideShowExtender").set_contextKey(x);
}
</script>
Here Text1 is our html textbox and Image1_SlideShowExtender is the ID of our SlideShowExtender.
The code in page method is written as follows:
[System.Web.Services.WebMethod] [System.Web.Script.Services.ScriptMethod]
public static AjaxControlToolkit.Slide[] GetSlides(string contextKey)
{
string keyword = contextKey;
XmlDataSource xmlData = new XmlDataSource(); xmlData.DataFile =
ConfigurationManager.AppSettings["flickrAPI"].ToString() + "&method=flickr.photos.search&text=" +
keyword + "&accuracy=1&safe_search=1&per_page=9&privacy_filter=1
&content_type=1&sort=relevance"; XmlDocument xmlDoc = xmlData.GetXmlDocument();
XmlNodeList xmlNodes = xmlDoc.SelectNodes("rsp/photos/photo"); AjaxControlToolkit.Slide[] slides = new AjaxControlToolkit.Slide[xmlNodes.Count];
for (int i = 0; i < xmlNodes.Count; i++)
{
slides[i] = new AjaxControlToolkit.Slide("http://farm" + xmlNodes[i].Attributes["farm"].Value + ".static.flickr.com/" + xmlNodes[i].Attributes["server"].Value + "/" + xmlNodes[i].Attributes["id"].Value + "_" + xmlNodes[i].Attributes["secret"].Value + "_m.jpg", xmlNodes[i].Attributes["title"].Value, "Photo-" + (i + 1).ToString() + ":");
}
return (slides);
}
This method takes the keyword we provided as contextKey and assigns it to the variable keyword. We get the data from Flickr in xml form by using the method flickr.photos.search and giving the required attributes to it, like the keyword, accuracy, safe search, number of images to be retrieved etc. The fetched data is displayed in the form of slideshow with images, title, photo name etc.
Communicationg with Web Services and WCF
Communication with Web Services in AJAX is purely client-centric development because the calls go to the services from client without the involvement of server.
Calling Web Services using MS-AJAX
- Microsoft AJAX technologies can pass data to and from Web Services
(This requires that the [ScriptService] attribute be applied to Web Service classes)
- AJAX‟s big win is invoking server code from the client page
- Web Services can be called using several different techniques:
AutoCompleteExtender and other controls
JavaScript
XML (This is in declarative method – but used very rarely)
Communication with Web Services in AJAX is purely client-centric development because the calls go to the services from client without the involvement of server.
Calling Web Services using MS-AJAX
- Microsoft AJAX technologies can pass data to and from Web Services
(This requires that the [ScriptService] attribute be applied to Web Service classes)
- AJAX‟s big win is invoking server code from the client page
- Web Services can be called using several different techniques:
- AutoCompleteExtender and other controls
- JavaScript
- XML (This is in declarative method – but used very rarely)
Normally WebServices follow open-standards and they are SOAP-enabled services/methods. Any request or response should be in SOAP-envelope format. JavaScript/ ASP.NET AJAX cannot use SOAP request and response. JavaScript supports JSON as its serializer and can be used across networks because it is also textual representation of data, but not XML/SOAP.
So Web Services can be used only if:
1. Web Service supports SOAP and additionally JSON requests
2. ASP.NET Web Services are AJAX-enabled (in other words JSON-enabled)
3. Service is WCF – because WCF can interact with different clients and AJAX is also one client.
ASP.NET AJAX can call a Web Service which is running in same domain where as JavaScript or page calls are present.
Anyhow we can design Web Methods that can interact with remote Web Services (even SOAP-enabled) and make local AJAX calls to our Web Method using JSON. This solution does not impact on performance because the call goes through the Web Service and not through the page.
ASP.NET AJAX Web Services Flow
(i) Client makes a request to proxy present locally in browser (proxy should be present in the browser)
(ii) Proxy takes the local call and converts to remote call as a JSON-serialized request
(iii) WebService which is JSON-enabled takes the request, serializes, deserializes, processes and then gives the results back in JSON format
(iv) Client proxy receives this JSON data and provides it to code as asynchronous results.
Note: We can use JavaScript databinding or JavaScript complex object handling to read this data and present it to server.
Generating proxy in ASP.NET AJAX
ScriptManager provides services tag where we can register a service. Once service is registered, automatically proxy is generated and most importantly attached to JS objects of project ( To get intellisense help we have to build it first). When page request is made ScriptManager as usual sends this proxy to client which enables user to make direct calls.
JSON-enabling a Web Service or Ajax-enabled Web Service
A service which is written with an attribute called [ScriptService] is AJAX-enabled Web Service. This class (ScriptService) is found in System.Web.Script namespace. For page methods we have to use [ScriptMethod] attribute.
Steps for creating a Web Service and consuming it using ASP.NET AJAX
1. Start a new WebSite ( not a Web Service)
2. Add new item and select Web Service (.asmx)
This creates a Web Service in the same domain of our page (VS 2008)
3. Uncomment the [ScriptService] attribute as this only makes service JSON-enabled.
4. If complex types are used then prepare classes with required properties and fields.
5. Go to created Web Service and add the web methods. These Web Methods will process the request of clients and respond with JSON outputs. One great advantage here is that complex types especially generics are supported by JSON (JavaScript) as well as ASP.NET Web Services. If return type is a complex type then use [GenerateScriptType(typeof(<complextypename>))] attribute for making the proxy to generate that complex type. This attribute should be written for every complex type that is used.
6. Go to the required web form, place ScriptManager and add the service references in SOAP or using properties window
7. Design the form according to requirement. We can use HTML as well as ASP.NET controls for design. But coding for both of them will be same.
8. Write a function in JavaScript to call the created Web Service Method.
Demo: Calling a Web Service that gives Job details from Jobs table when JobId is passed
- As explained in the above steps we create a WebSite and add a Web Service to it naming it as DemoService.
- As we are going to use a Web Method which returns a complex type called Job, we have to create Job class in our project. For this add a class and write the fields and properties for it.
public class Job
{
int _jobId, _maxLvl, _minLvl; string _jobDesc;
public int JobId
{
get { return _jobId; } set { _jobId = value; }
}
//Properties for other fields _maxLvl, _minLvl and _jobDesc
public Job()
{
//
// TODO: Add constructor logic here
//
}
}
- Now we write our WebMethod in the Web Service as given below:
[System.Web.Script.Services.ScriptService]
public class DemoService : System.Web.Services.WebService {
public DemoService () {
//Uncomment the following line if using designed components //InitializeComponent();
}
[GenerateScriptType(typeof(Job))] [WebMethod]
public Job GetJobInfo(int jobid)
{
SqlConnection cn=new SqlConnection("data source=mytoy; user id=sa; database=pubs");
string str="select * from jobs where job_id='"+jobid+"'"; SqlCommand cmd=new SqlCommand(str,cn);
cn.Open();
SqlDataReader dr=cmd.ExecuteReader(); Job obj=new Job();
if(dr.Read())
{
obj.JobId=Convert.ToInt32(dr[0]); obj.JobDesc=dr[1].ToString(); obj.MinLvl=Convert.ToInt32(dr[2]); obj.MaxLvl=Convert.ToInt32(dr[3]);
}
else
obj.JobId=-1; dr.Close(); cn.Close(); return obj;
}
}
This Web Method gets the Job details corresponding to the given JobId. It should be noted here that the return type is a complex type called Job. To generate that return type we are using the attribute [GenerateScriptType(typeof(Job))].
After creating this web service we go to the form from where we have to call the service. We place a ScriptManager and give the path of the service in it as given below:
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Services>
<asp:ServiceReference Path="~/DemoService.asmx" /> </Services>
</asp:ScriptManager>
Instead of manually writing it, we can specify it in the properties of ScriptManager by going to Services and selecting our service from the shown list. If a service is selected in properties, it will automatically reflect in the source code.
We design our form with a textbox and a button and also a table with four labels to display the retrieved data. We place this table in <div> and make its display to none so that initially it remains hidden and later when the data is retrieved we make its display to block so that the records are visible.
<div id="result"
style="display:none;width:700px; text-align:center"> <table border="1" >
<tr> <td><b>JobId</b></td>
<td><label id="l1"></label></td> </tr>
<tr>
<td><b>JobDesc</b> </td> <td><label id="l2"></label</td>
</tr>
<tr>
<td><b>Min Lvl</b></td> <td><label id="l3"></label></td> </tr>
<tr>
<td><b>Max Lvl</b></td> <td><label id="l4"></label></td>
</tr>
</table> </div>
Now we have to make a call to the WebService through the JavaScript code in our button click event. The code is given below:
function btnJob_onclick() {
var x = document.getElementById("Text1").value; DemoService.GetJobInfo(x, success,failed);
function success(result) { x=document.getElementById("l1"); x.innerHTML = result.JobId;
var d = document.getElementById("result"); if (x.innerHTML == -1) {
d.style.display = 'none'; alert("no job id exists"); return;
}
d.style.display = ''; x=document.getElementById("l2"); x.innerHTML = result.JobDesc; x=document.getElementById("l3"); x.innerHTML = result.MinLvl; x=document.getElementById("l4"); x.innerHTML = result.MaxLvl;
}
function failed(result) { alert("failed"); return;
}
}
Now when we run the program this JavaScript code calls the Webmethod GetJobInfo by passing the JobId which the user enters in the textbox. The function DemoService.GetJobInfo is called a callback function because it calls the WebMethod and gets back the data. The two additional parameters success and failed represent the status of the call. There is one more parameter which corresponds to timeout. We can specify any of these parameters and write code for them. If the call is a success it goes to the success function, if it is a failure it goes to failed function and if it is timeout it goes to timeout function. We can give any desired names to these parameters and write the corresponding function. In our example we have used only success and failed parameters. If the call is a success then we are giving the required data to the table to
display and if the call is failure we are displaying a failed message to the user. The screenshots corresponding to both the scenarios are shown here.
Success:
Failure:
Calling a Web Service using XML Script:
Till now we have seen two ways of calling Web Services in ASP.NET AJAX. One way was to directly call the service through some extender controls and another way was to call the service from JavaScript code. We can even call a Web Service using XML script, but that method is used very rarely because of the tedious coding involved.
Here databinding syntax is declared using XML script. The format of the script is as follows:
<script type="text/xml-script">
<page xmlns="http://schemas.microsoft.com/xml-script/2005"> <components>
//definitions
//serviceMethodRequest
</components>
</page>
</script>
The <scriptMethodRequest> element can be used to call a WebService.
Ex:
<serviceMethodRequest id="smCustomersByCountry" url="~/CustomerService.asmx" methodName="GetCustomersByCountry">
<bindings>
<binding dataContext="timeServiceMethod" dataPath="result" property="value" />
</bindings>
<completed>
//Handle data binding
</completed>
</serviceMethodRequest>
Communicating with WCF in AJAX
- WCF is Windows Communication Foundation.
- It is used to develop service oriented applications
- It is a unified model for developing distributed applications
To enable WCF for JSON
To enable WCF for JSON, an endpoint needs to be added in web.config file.
<services>
<service name="Test" behaviorConfiguration="MetadataSupport" >
<endpoint binding="webHttpBinding" behaviorConfiguration="jsonBehavior" bindingConfiguratin="jsonBinding" contract="ITest"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetaDataExchange"/>
</service> </services>
........
........
<bindings> <webHttpBinding>
<binding name="jsonBinding" messageEncoding="json">
<webHttpBinding> </bindings>
<behaviors> <serviceBehavior>
<behavior name="metadataSupport"> <serviceMetadata httpGetEnabled="true"
httpGetUrl="">
</behavior>
</serviceBehavior>
<endpointBehaviors>
<behavior name="jsonBehavior"> <enableWebScript/>
</behavior> </endpointBehaviors>
</behaviors>
Steps for developing WCF-enabled AJAX Service
1. Start a new WebSite
2. Add new item à AJAX-Enabled WCF Service
Result is simple class which is WCF-enabled class. Add methods as usual with an attribute [OperationContract]
3. Build the application
4. Go to page, place ScriptManager and register the service (.svc)
5. Write JS proxies and consume as usual with success, failure etc.
Demo- Using Entity Framework, WCF and ASP.NET AJAX
In this demo we use Entity Framework model for our service and call the service with AJAX. The service gets the image and price of a product from Product table by taking its ProdId as input. We use ADO.NET Entity Framework in the service method. For preparing the entity objects we add new item and select ADO.NET Entity Data Model and name it as Eshop. Using it we select the Product table from the datasource. This creates the object of Product table in our application. Now we can proceed to write our service method for retrieving the desired records. First the service is created by selecting the AJAX-Enabled WCF Service and name it as Products. The service method is written with the attribute [OperationContract] as given below:
[OperationContract]
public List<string> GetProduct(int ProdId)
{
EshopModel.EshopEntities obj = new EshopModel.EshopEntities(); var x = (from n in obj.Products
where n.ProdId == ProdId select new
{
Image = n.Prodview, Price = n.Price
}).FirstOrDefault(); List<string> s = new List<string>(); if (x != null)
{
s.Add(x.Image);
s.Add(x.Price.ToString());
}
else
{
s.Add("Notfound.jpg"); s.Add("Not found");
}
return s;
}
It should be noted that in this method we are using Generics(list of strings) and anonymous types which are new additions in C# 3.0 version. After creating this service we have to build it first to be able to use it.
Now we‟ll go to our page and place the ScriptManager in it. We have to refer the service by adding its path in service references of service property of ScriptManager.
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Services><asp:ServiceReference Path="~/Products.svc" />
</Services> </asp:ScriptManager>
Then we design the page as required using a textbox, button and an image control (all html controls). Now we write our code to call the service in button click property. function Btn_click() {
var x = document.getElementById("Text1").value; Products.GetProduct(x, success, failure); function success(result) {
var img = document.getElementById("img1"); img.src = result[0];
img.alt = result[1];
}
function failure(result) { alert(result.get_exceptionType()); alert("failed:", result.toString());
}
Now when the ProdId is entered in the textbox and the button is clicked, it calls the service method which in turn fetches the record and gives the result to calling function.
When the mouse pointer is moved over the image, it shows the price of the product also.
If the record is not found, then it displays the notfound image.
We have seen how to create a WCF service using Entity Framework and then consume it using AJAX. Similarly we can even work with any other services also.
No comments:
Post a Comment