Click here to Skip to main content
15,881,668 members
Articles / Web Development / HTML

Magic AJAX: Applying AJAX to your existing Web Pages

Rate me:
Please Sign up or sign in to vote.
4.82/5 (72 votes)
28 May 2007MIT12 min read 965K   2.7K   251  
How to apply AJAX technologies to your web pages without replacing ASP.NET controls and/or writing JavaScript code.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>MagicAjax.NET Configuration</title>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
		<style type="text/css"> <!-- .MainHeader { font-weight: bold; color: white; background-color: #0066cc; font-size: 10pt}
	body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; color: black; background-color: white}
	.BorderHeader { background-color: #999900; font-size: 8pt; font-weight: bold; color: #333300; text-align: center}
	.MainContent { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; color: black }
	.BorderContent { font-size: 8pt; color: black; border-color: black #666600 #666600; padding-top: 2px; padding-right: 2px; padding-bottom: 10px; padding-left: 2px; margin-bottom: 2px; border-style: solid; border-top-width: 0px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px}
	a:link { color: #000099; text-decoration: underline}
	a:hover { color: #000099; text-decoration: underline}
	a:visited { color: #000099; text-decoration: underline}
	li { color: black; list-style-type: circle; position: relative; left: -15px; clip: rect( )}
	.NewsDate { color: black; font-weight: bold; font-size: 11pt}
	td { font-size: 10pt}
	th { font-size: 10pt}
	.Annotation { font-size: 10px}
	H1 { text-align: center; }
	A.qindex {}
	A.qindexRef {}
	A.el { text-decoration: none; font-weight: bold }
	A.elRef { font-weight: bold }
	A.code { text-decoration: none; font-weight: normal; color: #4444ee }
	A.codeRef { font-weight: normal; color: #4444ee }
	DL.el { margin-left: -1cm }
	DIV.fragment { width: 100%; border: none; background-color: #003300 }
	DIV.ah { background-color: black; margin-bottom: 3; margin-top: 3 }
	TD.md { background-color: #006600 }
	DIV.groupHeader { margin-left: 16; margin-top: 12; margin-bottom: 6; font-weight: bold }
	DIV.groupText { margin-left: 16; font-style: italic; font-size: smaller }
	FONT.keyword { color: #008000 }
	FONT.keywordtype { color: #999920 }
	FONT.keywordflow { color: #e0FF00 }
	FONT.comment { color: #009900 }
	FONT.preprocessor { color: #809020 }
	FONT.stringliteral { color: #002080 }
	FONT.charliteral { color: #008080 }
	H3 { FONT-FAMILY: trebuchet ms,helvetica,arial }
	.ex { FONT-SIZE: 8pt; FONT-FAMILY: tahoma }
	CODE.keywordtype { COLOR: #00ccff }
	CODE.keyword { FONT-WEIGHT: bold; COLOR: #00ccff }
	CODE.fn { COLOR: white; FONT-WEIGHT: bold; }
	CODE.var { COLOR: #dcdcdc; }
	CODE.macro { COLOR: #809020; FONT-WEIGHT: bold; }
	CODE.comm { COLOR: lime }
	CODE.num { COLOR: purple }
	CODE.str { COLOR: #ffcc33; font-style: italic }
	.SectionHeader { font-size: 14px; color: #FFFFCC; font-weight: bold}
	.header { font-size: 16px; font-weight: bold; color: #663399}
	--></style>
	</head>
	<body text="#000000" bgColor="#ffffff">
		<p class="header" align="center">MagicAjax.NET Framework</p>
		<P class="header" align="center">Configuration</P>
		<p class="MainHeader" align="left">Table of Contents</p>
		<UL>
			<LI>
				Setting configuration options
				<ul>
					<li>
						<A href="#webconfig">Web.config</A>
					<li>
						<A href="#bycode">By code</A>
					</li>
				</ul>
			<LI>
				Configuration options
				<ul>
					<LI>
						<A href="#scriptPath">ScriptPath</A>
					<li>
						<A href="#OutputCompareMode">OutputCompareMode</A>
					<LI>
						<A href="#tracing">Tracing</A>
					<li>
						PageStore
						<ul>
							<li>
								<A href="#Mode">Mode</A>
							<li>
								<A href="#UnloadStoredPage">UnloadStoredPage</A>
							<li>
								<A href="#CacheTimeout">CacheTimeout</A>
							<li>
								<A href="#MaxConcurrentPages">MaxConcurrentPages</A>
							<li>
								<A href="#MaxPagesLimitAlert">MaxPagesLimitAlert</A>
							</li>
						</ul>
					</li>
				</ul>
			</LI>
		</UL>
		<p class="MainHeader" align="left">Setting Configuration Options</p>
		<p class="NewsDate"><a name="webconfig"></a>Web.config</p>
		<p class="MainContent">You can set the configuration options for MagicAjax inside 
			web.config's <i>configuration</i>
		section. The options will be applied to all the pages of your application that 
		use MagicAjax. If you ommit an option from web.config, MagicAjax will use its 
		default setting. A sample of MagicAjax's default configuration options is this:
		<P class="MainContent">(<b>note:</b> There is a sample web.config file inside the 
			'Core' folder of the distribution with short descriptions for each available 
			option)
			<pre>	&lt;configSections&gt;
		&lt;section name="magicAjax" 
			type="MagicAjax.Configuration.MagicAjaxSectionHandler, MagicAjax"/&gt;
	&lt;/configSections&gt;

	&lt;magicAjax
		outputCompareMode="HashCode"
		tracing="false"&gt;
		&lt;pageStore
			mode="NoStore"
			unloadStoredPage="false"
			cacheTimeout="5"
			maxConcurrentPages="5"
			maxPagesLimitAlert="false"
		/&gt;
	&lt;/magicAjax&gt;</pre>
			<hr>
		<P></P>
		<p class="NewsDate"><a name="bycode"></a>By code</p>
		<p class="MainContent">The web.config MagicAjax settings can be overriden for a 
			particular page, by code. The <b>MagicAjaxContext.Current.Configuration</b> property 
			carries all the options and you can change any of them at the Load event of 
			your page. Example:
			<pre>	private void Page_Load(object sender, System.EventArgs e)
	{
		MagicAjaxContext.Current.Configuration.PageStore.Mode = MagicAjax.Configuration.PageStoreMode.Session;
	}</pre>
			Any changes you make to the configuration options by code will be stored in a 
			hidden field of the page and will be restored for a PostBack/AjaxCall. Thus, 
			the following example has the same effect as the previous:
			<pre>	private void Page_Load(object sender, System.EventArgs e)
	{
		if ( !IsPostBack )
		{
			MagicAjaxContext.Current.Configuration.PageStore.Mode = MagicAjax.Configuration.PageStoreMode.Session;
		}
	}</pre>
			<b>Note:</b>
		Configuration options can be changed during a PostBack, but changing&nbsp;them 
		during an AjaxCall is not allowed and will throw an exception.
		<P></P>
		<p class="MainHeader" align="left">Configuration Options</p>
		<p class="NewsDate"><a name="scriptPath"></a>ScriptPath</p>
		<p class="MainContent"><b>Type:</b> string<br>
			<b>Default:</b> null (omitted)<br>
			<b>Description:</b> MagicAjax's script files are embedded in the dll and are 
			put on page using script tags like this:
			<pre>	&lt;script type="text/javascript" src="AjaxCallObject.js.aspx"&gt;&lt;/script&gt;</pre>
			If you set ScriptPath to a value, the <i>src</i> attribute of the script tag 
			will contain the path of ScriptPath. That way you can use your own modified 
			versions of MagicAjax's script files. Example:
			<pre>	&lt;magicAjax ScriptPath="~/script" /&gt;</pre>
			<hr>
		<P></P>
		<p class="NewsDate"><a name="OutputCompareMode"></a>OutputCompareMode</p>
		<p class="MainContent"><b>Type:</b> enumeration (HashCode / MD5 / FullHtml)<br>
			<b>Default:</b> HashCode<br>
			<b>Description:</b>
		When an AjaxCall is invoked, MagicAjax compares the previous html renderings of 
		controls included in an AjaxPanel with the current ones, to see if changes 
		occured. Instead of keeping the complete html string, MagicAjax produces 
		'fingerprints' of the html rendering strings to&nbsp;compare them. When 
		'NoStore' PageStore mode is selected,&nbsp;the fingerprints are kept on page in 
		hidden fields. This option defines how the fingerprints are going to be 
		produced:
		<P class="MainContent"><b>HashCode:</b>
		The String.GetHashCode() method is used. This produces the smaller in size 
		fingerprints but with the bigger chance for collisions.
		<P class="MainContent"><b>MD5:</b>
		MD5 hashing is used. It is slower and larger in size, but practically there is 
		no chance for collisions.
		<P class="MainContent"><b>FullHtml:</b> The full html rendering is kept. This is 
			provided only for debugging purposes.
			<hr>
		<P></P>
		<p class="NewsDate"><a name="Tracing"></a>Tracing</p>
		<p class="MainContent"><b>Type:</b> boolean<br>
			<b>Default:</b> false<br>
			<b>Description:</b> If tracing is enabled, when an AjaxCall is invoked, a 
			tracing window is created that displays the information about the data that 
			were sent by the client&nbsp;to the server as POST data and the javascript code 
			that the client received as a response from the server. That way you can 
			monitor the traffic of AjaxCalls for debugging purposes or to find a page setup 
			with less AJAX traffic.
			<hr>
		<P></P>
		<p class="NewsDate"><a name="Mode"></a>PageStore - Mode</p>
		<p class="MainContent"><b>Type:</b> enumeration (NoStore / Session / Cache)<br>
			<b>Default:</b> NoStore<br>
			<b>Description:</b>
		This is the option that has the most impact on how MagicAjax is going to 
		function and to the page's execution cycle. Study the different modes carefully 
		before deciding which one suits the needs of your application.
		<P class="MainContent"><b>NoStore</b>
		: The default and recommended PageStore mode. The page's execution cycle for an 
		AjaxCall is the same as a PostBack. The page and its controls are recreated at 
		each AjaxCall, nothing is kept on the server, and the ASP.NET control events 
		(Load, Unload etc.) are raised. This mode works for both NET 1.1 and NET 2.0.
		<P class="MainContent"><b>Session</b>
		: The page object of the request is stored at the server in Session, 
		and&nbsp;MagicAjax raises the various events on the stored page object. This 
		mode bypasses the ASP.NET Page execution cycle; the control events (Init, Load, 
		PreRender, Unload) are not raised but instead MagicAjax's stored page events 
		are raised (AjaxCall, PreWriteScript, AjaxCallEnd) and the PostBack events of 
		controls (Click, SelectedIndexChanged, CheckChanged etc.)
		<P class="MainContent">In order to handle the stored page events you need to 
			implement the appropriate interfaces (IAjaxCallEventHandler, 
			IPreWriteScriptEventHandler) on your Page/Usercontrol/Custom control class, or 
			use AjaxPage/AjaxUserControl (see <A href="Usage.html#AjaxPage">Usage</A>
		).
		<P class="MainContent">This mode offers better performance than 'NoStore' and less 
			AJAX traffic, at the expense of consuming server's memory. Also, keeping the 
			page object 'alive' has the benefit that any control that gets created during 
			an AjaxCall, will be available during the next AjaxCall. For example, if you 
			wanted to have a button that every time it is clicked, a new checkbox is added 
			in a panel, here's how you can do it with an AjaxPanel and 'Session' mode:
			<pre>	private void Button1_Click(object sender, System.EventArgs e)
	{
		CheckBox check = new CheckBox();
		check.Text = "Checkbox" + AjaxPanel1.Controls.Count;
		AjaxPanel1.Controls.Add (check);
	}</pre>
		On the other hand, if you wanted to do the same with a normal PostBack or 
		'NoStore' mode, you would have to implement code that keeps track of the 
		created CheckBoxs and recreate them at the Load event. The 'alive' page object 
		can be programmed almost like a desktop application form.
		<P></P>
		<P class="MainContent">This mode has drawbacks that you must consider:
			<ul>
				<li>
				It works only with 'InProc' Session state mode; it will not work with 
				'StateServer' or 'SQLServer' Session state modes.
				<li>
				It is supported only for NET 1.1
				<li>
					HtmlAnchor and HtmlImage controls loose their attributes during an AjaxCall; 
					AjaxHtmlAnchor and AjaxHtmlImage should be used in their place. (see <A href="Usage.html#AjaxHtml">
						Usage</A>)
				</li>
			</ul>
		<P class="MainContent"><b>Cache:</b> This mode works like 'Session' with the only 
			difference being that the page object is stored in server's Cache, so the 
			'StateServer' and 'SQLServer' Session state modes can be used.</P>
		<P></P>
		<P>
			<hr>
		<P></P>
		<P></P>
		<p class="NewsDate"><a name="UnloadStoredPage"></a>PageStore - UnloadStoredPage</p>
		<p class="MainContent"><b>Type:</b> boolean<br>
			<b>Default:</b> false<br>
			<b>Description:</b> (Applicable only to <b>Session/Cache</b> PageStore modes) 
			If the page object is stored (Session/Cache PageStore modes), this option 
			defines whether the stored page object should be dropped when the browser's 
			page is unloaded (when the user closes the window, navigates to another page, 
			etc.). If it is enabled, an invisible AjaxCall is invoked at the Unload event 
			of the browser's page, requesting that the server should drop the page object 
			immediately. Although this can reduce a bit the memory consumption of page 
			storing modes, it has the drawback that the page's state is not kept in 
			browser's cache, so if the user returns to the MagicAjax-enabled page using the 
			browser's Back button, the page will not have kept&nbsp;any AJAX changes and 
			the user will see the initial page before any AjaxCalls were invoked.
			<hr>
		<P></P>
		<p class="NewsDate"><a name="CacheTimeout"></a>PageStore - CacheTimeout</p>
		<p class="MainContent"><b>Type:</b> integer<br>
			<b>Default:</b> 5<br>
			<b>Description:</b> (Applicable only to <b>Cache</b> PageStore mode) Defines 
			the time in minutes that the page object will be kept in server's Cache, if 
			Cache PageStore mode is selected.
			<hr>
		<P></P>
		<p class="NewsDate"><a name="MaxConcurrentPages"></a>PageStore - MaxConcurrentPages</p>
		<p class="MainContent"><b>Type:</b> integer<br>
			<b>Default:</b> 5<br>
			<b>Description:</b> (Applicable only to <b>Session/Cache</b>
		PageStore modes) Every new page request creates a new page object on the 
		server. MagicAjax distinguishes page objects based on the user's session id 
		and&nbsp;the requested page. If the user opens, in his session, the same page 
		more than once, MagicAjax stores the page objects that belong to the same page 
		and session, but only until MaxConcurrentPages limit is reached. If the limit 
		is reached and the user requests the same page in his session, MagicAjax will 
		not&nbsp;store the new page object, but instead it will find the page object 
		that was accessed less recently and use this for the new page request as well.
		<P class="MainContent">If the MaxConcurrentPages limit didn't exist, a new page 
			object would have to&nbsp;be created and stored on the server every time the 
			'Refresh' button of the client's browser was clicked.
			<hr>
		<P></P>
		<p class="NewsDate"><a name="MaxPagesLimitAlert"></a>PageStore - MaxPagesLimitAlert</p>
		<p class="MainContent"><b>Type:</b> boolean<br>
			<b>Default:</b> false<br>
			<b>Description:</b> (Applicable only to <B>Session/Cache</B> PageStore modes) 
			If this option is true, when a page request by the user reaches the <b>MaxConcurrentPages</b>
			limit, a notification alert box appears. Provided mainly for debugging 
			purposes.
			<hr>
		<P></P>
		<P class="MainHeader" align="left">&nbsp;</P>
		<P>Copyright � 2005-2006 by The MagicAjax.NET Team</P>
	</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Web Developer
Greece Greece
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions