

Problem 2: Using CSS is very good practice but serving stylesheets as separate resources, thus causing separate requests, should be considered very carefully.
Solutions:
Problem 3: JavaScript is an awesome scripting language which can be quite powerful to play with. Nonetheless, it should be used carefully not only for request size issues; but also because it can have a way of causing unpredictable performance issues.
Solution:
Inline JavaScript could make the HTML page heavy, so it’s preferred to serve separate .js files or a single JavaScript file to keep all JavaScript-based scripts in a single place.
JavaScript files also get cached automatically by browsers, so they usually aren’t requested each time the page is loaded by the browsers.
2. HTTP Compression:
HTTP Compression is used to compress contents from the web server. HTTP requests and responses could be compressed, which can result in great performance gains. Through HTTP compression, the size of the payload can be reduced by about 50%, which is great. Isn’t it?
HTTP Compression is now widely supported by browsers and web servers.
If HTTP compression is enabled on the web server, and if the request header includes an Accept-Encoding: gzip, deflate header, the browser supports gzip and deflate compression mechanisms, so the response can be compressed in any of the given formats by the web server in order to reduce the payload size. This leads to an increase in performance. Latter that compressed response is decompressed by the browser and rendered normally.
Following are very good links which detail HTTP Compression and their implementations:
3. Correct Formatted Images at the Right Place:
Problem: Normally designers use JPG or GIF formats quite randomly and ignore some other good formats to compress images.
Solution:
Correct format should be used for right purpose like:-
If you have to place a background image, some large image or a screenshot then the suggested format is JPG/JPEG.
If you have to use small graphics like button images, header images, footer images, navigation bar images or clip arts, then the suggested format is PNG.
If an image is not required to be in high or true colors and 256 colors are enough, then GIF is preferred.
4. Compress CSS, JavaScript and Images
CSS files (.css), images and JavaScript (.js) files can be compressed, as normally .css and .js files contain unnecessary spaces, comments, unnecessary code and such other things. A number of high quality (and free) utilities are available to help you pre-compress your files.
Following are a few good links for such utilities:
5. CSS at Top
The recommended approach is to put CSS links on top of the web page, as it makes the page render progressively efficient. Since users want to see the contents of a page whilst it’s loading rather than white spaces, contents/formats should be given on top. HTML Specifications clearly say to declare style sheets in the head section of a web page.
6. Javascript at Bottom
When scripts are defined on top of the page they can take unnecessary time to load; they don’t show the contents that users are expecting after making any request to an HTTP web server. It's better to display a the HTML contents of a page, then load any scripting code (when possible, of course).
Preferably use/link up JavaScript-based scripts at the bottom of a web page. Alternatively you can use the defer attribute, which runs the script at the end of page loading, but that is not the preferable approach as it is not browser independent. For example, Firefox doesn’t support it and could mess up with document.write, so only use it once you fully understand the implications.
7. Content Delivery Network: (CDN)
When a browser makes a request to any web page – that is, he types a URL/URI of any web page or web site, a request goes through many hops (routers and computers) and then finally reaches its final destination. This happens both for requests and responses. This operation affects performance and can severely effect load time.
A Content Delivery Network implies a collection of computers, distributed all over the world, which deliver data (contents). Through a CDN you can have your website data on multiple servers distributed in different locations around the world. Distribute web application data in different places around the world so request can be served from the nearest location and save time (which means performance and money as well).
8. Ajax
Problemm: Ajax is being increasingly used to improve usability, but oftentimes in a way which increases overall server load.
Solutions:
Preferably use the GET method for Ajax based Requests, because if you use POST method then the request header would be sent first, followed by the data, which basically splits the request in two steps. A single-step request can be achieved with GET if a cookie is not too long and the URL is not larger than 2k.
When using ASP.NET AJAX and the UpdatePanel control for partial page rendering, use the maximum number of update panels to update small chunks of page, but use them wisely. Don’t set the Update property to Always unless needed. Instead, set the update mode to Conditional, otherwise all the partial chunks would be sent together after each asynchronous postback.
Ajax based requests can also be cached when using the GET method. If the URL is the same, then cached data can be used from the client, and a round trip to the server can be avoided.
9. Ajax vs. Callback
Problem: Ajax is a great solution for asynchronous communication between client (web browser) and HTTP servers, but one solution can't be applied to every problem. This means that Ajax is great mechanism for sending requests to the server without making a full page postback, but what if you need to send a request to the server and don’t even need partial rendering?
Solution: Best solution is Callback.
For example, if you need to check whether a user exists or not, or if a user has forgotten his/her password and you just need to send a request to the server to check if user name exist, there is no need for client-side render - just a server side operation.
Following are a couple of great links which explain callbacks: Please click herehere.
and
10. Reduce Cookie size
Cookies are stored on the client side to keep information about users (authentication and personalization). Since HTTP is a stateless protocol, cookies are common in web development to maintain information and state. Cookies are sent with every HTTP requests, so try to keep them low in size to minimize effects on the HTTP response.
11. Use Cache appropriately
Cache mechanism is a great way to save server round trips - and also database server round trips - as both round trips are expensive processes. By caching data we can avoid hitting them when unnecessary. Following are few guidelines for implementing caching::
Following are few very good links to implement caching for different types of data (static and dynamic):
12. Upload compiled code rather than source code
Pre-compiled ASP.NET pages perform much better than source code versions. Actually pre-compilation give web sites a performance boost especially when the first request is made to a folder containing that resource. Uploading a pre-compiled version boosts up performance since the server doesn’t need to compile a page at request-time.
13. Conclusions
Following are few good practices to gain better performance::
What is an extender? The AJAX Control Toolkit
uses extenders to provide additional capabilities that go beyond what the normal ASP.NET controls can do out-of-the-box. This is because these extenders use client-side script to perform animations, transformations, or other cool effects. These features are available in DHTML
, while some may be browser-specific; however, to the developer, the extender handles all the work through the script that it emits, and all we need to worry about is the setup of the extender.
To use the toolkit, you have to download it (the link is in the References section), and unzip it in your Visual Studio 2005\Projects folder. Navigate to the SampleWebSite\bin directory to get to the AjaxControlToolkit.dll
file, which contains all of the extenders. In the code sample, I used the following web configuration setup in the pages element:
<add
tagPrefix="ajaxtoolkit"
namespace="AjaxControlToolkit"
assembly="AjaxControlToolkit" />
Using this following configuration, I setup a sample that allows the user to enter a phone number. The code segment is as follows:
Enter a Phone Number:
<asp:TextBox ID="txtPhoneNumber" runat="server" />
<ajaxtoolkit:FilteredTextBoxExtender
ID="extPhoneNumber"
runat="server"
TargetControlID="txtPhoneNumber"
FilterType="Numbers, Custom"
ValidChars="-">
ajaxtoolkit:FilteredTextBoxExtender>
Notice that the textbox
doesn't have anything special added to it; the extender emits script for it, which an extender is linked to it through the TargetControlID
(a consistent property
to target a control
throughout the control library). The other properties that were used were:
FilterType
- The filter type is an enumeration
that supports multiple assignments separated by a comma. It has possible values of LowerCaseLetters
, UpperCaseLetters
, Numbers
, and Custom. In the above example, I use Numbers and Custom options. ValidChars
- When using Custom FilterType
, the ValidChars property
contains a listing of characters that are the only ones allowed in the textbox
. The effective result is that only numbers and the - character are allowed to be typed in to the textbox
. No other values can be keyed in. However, validation is still needed to ensure that the values are in the correct order (this extender doesn't require the values be in any order). In the above example, I would have still needed that a RegularExpressionValidator
be used to ensure a correct format. This is a way though, to ensure that the correct results are provided in your applications that you develop.
How would you set this up for name? FilterType
has a combination of UppercaseLetters
and LowercaseLetters
that can be used; however, this doesn't take care of the space. This means that the Custom option must be used as well, allowing for a ValidChars
parameter of " ". Using this, you can also ensure that only the correct name data can be entered. The example is below:
Enter your Name:
<asp:TextBox ID="txtName" runat="server" />
<ajaxtoolkit:FilteredTextBoxExtender
ID="extName"
runat="server"
TargetControlID="txtName"
FilterType="UppercaseLetters,LowercaseLetters,Custom"
ValidChars=" " />
When running the form, this filter actually restricts the keyboard from entering values outside this range. Only letters and spaces are allowed to be typed in. The extender adds a script reference that points to a script stored as an embedded resource in the DLL
for the control library
, and the reference is generated dynamically. Using this extender, you can see a means to make validation of data easier in your applications.
Silverlight
is a browser plug-in that that extends the web development experience far beyond the limitations of plain HTML
and JavaScript
. Being a Microsoft product, you might expect it to work best (or only) on Windows and Internet Explorer. So you may be pleasantly surprised to know that it works equally well on Windows and on the Mac, and it also works equally well on the Firefox and Safari web browsers. Since Silverlight
is a client side technology, it doesn't matter what backend server software or platform you're running - even Apache/Linux will do just fine.
Silverlight
version 1.0 - scheduled for release this summer - is very comparable to Adobe Flash. It delivers high performance multimedia and animation capabilities that can blend seamlessly with HTML. It's capable of playing a variety of audio and video file formats, such as MP3, WMA, and WMV. It handles streaming quite well, so media can start playing immediately without having to wait for the entire file to download.
Silverlight's user interface is defined with a subset of XAML - an XML format shared with Windows Presentation Foundation (WPF). This facilitates vector based animations, a claim that goes beyond Flash's current capabilities. Silverlight's compiled object model can be navigated via JavaScript
for seamless interaction between embedded Silverlight
components and the page that hosts them.
When users encounter a Silverlight
1.0 enhanced web page for the first time, they'll be prompted with the quick & easy installation that's only about a 1.2 megabyte download.
You can download the beta version of Silverlight 1.0 now.
While the multimedia and animation capabilities of Silverlight
1.0 are certainly great for graphic designers, Silverlight
version 1.1 (currently in alpha) starts to provide the kind of business oriented functionality that the majority of web developers need.
Probably the most exciting feature of version 1.1 is the built-in cross platform subset of the .NET
Framework. While you can still mix in as much (or as little) JavaScript
as you'd like, you'll now have the option of running your own fully compiled .NET
code within IE, Firefox, or Safari. Those developers who hate JavaScript
should be thrilled to know they can now write their client side code in C#
, VB.NET
, or any other .NET
language. This .NET
code can interact with the browser's object model so it can manipulate the page's HTML
in addition to interacting with any Silverlight
user interface that may be embedded in the page. You'll now be able to replace slow performing JavaScript
code with fully compiled .NET code that could easily execute hundreds of times faster.
A variety of useful classes are included in Silverlight
1.1 for working with cutting edge technologies like LINQ, generics
, multithreading
, and invocation
of Windows Communication Foundation (WCF) web services. There's also support for XML manipulation, networking, I/O, collections, globalization, and JSON
serialization.
ASP.NET
support is also provided for things like personalization, profiles, role membership, and invocation of ASMX web services. On a related note, the next release of ASP.NET is expected to include a variety of tools for easing Silverlight
development, including built-in controls that make it easy to embed Silverlight
content.
Unfortunately there are currently no definite plans to include any significant number of controls in Silverlight
1.1 - not even a basic button
control is currently in the mix. They do at least provide a control class that can be used to build your own controls, and alternately it's not terribly difficult to make basic controls using XAML
and some custom code - but certainly we'd prefer not to have to write such basic code. Luckily there are several controls available in the separate Silverlight 1.1 Alpha SDK download.
Since Silverlight
1.1 is still only in alpha, its uncertain exactly what other functionality may ultimately make it into the release version. The current download size for this far more functional version of Silverlight
hovers at around 4MB.
From my conversations with Silverlight
mastermind Scott Guthrie and his merry band of genius underlings, they've got a lot of mouthwatering functionality planned for upcoming versions of Silverlight
. General themes include a rich set of built-in controls, data binding support, XLINQ
, RSS, Xml Serialization, Opera support, and improved layout management. And that's just for starters.
In general the vision is to transform Silverlight
from its current 1.0 state of multimedia powerhouse into a highly productive business tool capable of powering rich applications of virtually every kind.
Even with all this extra functionality, Silverlight's team has a long term secret goal of keeping the download size under 5MB. Shhhh! Don't tell anybody!
Currently the lack of polished tools for developing Silverlight
applications is its biggest hindrance. The next version of Visual Studio (codenamed Orcas) is expected to ship with rich Silverlight
support. However, the current beta version of Orcas
clearly still needs a lot of work before achieving this goal. If you're brave enough to be tinkering with the Orcas beta then you might as well download the Silverlight Tools Alpha add-on to try out its Silverlight
development capabilities.
Microsoft's new Expression suite of products is currently closer to being in a finished state. They are presently more polished and less buggy than Orcas
. Specifically, Expression Blend is probably the most valuable Expression product for Silverlight
development. However, be forewarned that the Expression suite is intended more for graphic designers than software developers. Therefore Visual Studio-oriented developers should expect a significant learning curve.
Silverlight
is a brilliant idea that still has a ways to go before it reaches its potential. Nevertheless, it should definitely be on every web developer's radar. It's a distinct possibility that Silverlight
could be the future of web development. Imagine a world where web developers no longer deal with HTML, and instead write rich, compiled .NET code that runs everywhere as ubiquitously as HTML
does now. If Microsoft plays its cards right, this will happen.
ASP.NET 2.0 has made quite a few enhancements over ASP.NET 1.x in terms of handling common client-side tasks. It has also created new classes, properties and method of working with JavaScript code. This article explores the enhancements and the various ways of injecting JavaScript programmatically into ASP.NET 2.0 pages.
In ASP.NET 1.x days, many client-side tasks, such as tracking mouse events, setting page focus, displaying/hiding a section of page, was not directly supported by asp.net. This is because ASP.NET applications are server-based; all web control events are handled on the server side. The constant round trips to and from server often slows down work processes, and the page-refreshing often ensured a web form would to lose its focus or its scroll position. Therefore programmers still rely on a multitude of JavaScript to keep web pages nimble and responsive. However, in ASP.NET 1.x, injecting JavaScript always involves two steps and quite some code: First, you weave your JavaScript function into a string in your code-behind page; second, you use the Page
class of your web form to register the script, using either the Page.RegisterStartupScript
or the Page.RegisterClientScriptBlock
method.
ASP.NET 2.0 has inherited some of the ASP.NET 1.x approaches of including JavaScript in a web form. Moreover, it has added many methods and properties to smooth and simplify the handling of some of the most common client-side tasks. It has also introduced new ways to include JavaScript on the server side or load JavaScript from resources. In this article will go into detail of the enhancements and the various ways of working with Script code in ASP.NET 2.0.
In this section, we will consider three common client-side tasks that ASP.NET 2.0 have made as easy as setting properties of controls.
1. Setting focus to web controls
In ASP.NET 1.x, it is not possible to programmatically set focus to a web server control without a bit help from the JavaScript's function focus()
. Here is how it was commonly done in C#:
//ASP 1.x method of setting focus to a specific control. You need
//to first pass the control's id as the parameter, then define the
//JavaScript function in a string variable then call the Page class
//to register the script. You may use either RegisterStartupScript()
//or RegisterClientScriptBlock() method.
private void SetFocus(String ctrlID)
{
// Build the JavaScript String
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("")
// Register the script code with the page.
Page.RegisterStartupScript("FocusScript", sb.ToString());
}
However, in ASP 2.0, there are three ways to dynamically set the focus to a specific control, all in just one line of code. You pass the control ID as the parameter and call the Page.SetFocus(control)
method, which enables you to set the focus to a particular control immediately after a page is initiated or loaded.
void Page_Init(object sender, EventArgs e)
{
SetFocus(ControlToSetFocus);
}
Or you can call the Focus
method that is available to all web controls. You can call it in the Page_load event or based on a user's response to set up a skip pattern. For example, if you have a TextBox
web control called Textbox1
, you may simply call:
TextBox1.Focus();
ASP 2.0 web forms also have a property called DefaultFocus
. By setting the DefaultFocus
property, you can set the focus to a desired control when page loads.
For example, the code below will automatically set the focus on TextBox2
when the web form is loaded:
<form defaultfocus="textbox2" runat="server">
<asp:textbox id="textbox1" runat="server"/>
<asp:textbox id="textbox2" runat="server"/>
form>
2. Popping up Message Boxes
Confirming with users before they take actions with potentially irreversible consequences like record deleting is a common practice, so is alerting users about important information with a JavaScript alert box. In ASP.NET 1.x, with either a delete column of a DataGrid
, or a regular web control, we need to attach the JavaScript alert(msg)
or confirm(msg)
function to the control's attributes or register the script with the Page
class.
For example, we can use the following code to add the alert script to a button control:
<script language="C#" runat="server">
protected void Page_Load(object sender, EventArgs e){
//Set the button's client-side onmouseover event
btnClick.Attributes.Add("onClick", "alert('Ouch, you clicked me!');");
}
script>
<form runat="server">
<asp:button runat="server" Text="Click Me!" id="btnClick" />
form>
Or similarly we can attach the confirm(msg)
script to a button.
<script language="C#" runat="server">
protected void Page_Load(object sender, EventArgs e){
//Set the button's client-side onmouseover event
btnDelete.Attributes.Add("onClick",
"return confirm('You sure you want to delete the record?');");
}
script>
<form runat="server">
<asp:button runat="server" Text="Delete!" id="btnDelete" />
form>
However, with a ASP.NET 1.x DataGrid
, we need to place the code for confirm messagebox in the DataGrid's OnItemDataBound
or OnItemCreated
event handler. The code below shows how this can be done in the OnItemDataBound
event.
<script language="c#" runat="server">
private void DataGrid1_ItemDataBound(Object sender, DataGridItemEventArgs e)
{
// First, make sure we're NOT dealing with a Header or Footer row
If (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem )
{
//Assume the first column of DataGrid1 is the Delete ButtonColumn
LinkButton deleteButton = e.Item.Cells(0).Controls(0);
//We can now add the onclick event handler
deleteButton.Attributes.Add("onclick",
"javascript:return confirm('Are you sure you want to delete
this record?')";
}
}
script>
<form runat="server">
<asp:datagrid id="DataGrid1" runat="server"
...
OnItemDataBound="DataGrid1_ItemDataBound">
...
asp:datagrid>
form>
In ASP.NET 2.0, to add a client-side message box is just a matter of setting the OnClientClick
property, as the following:
<asp:Button ID=button1 runat=server
OnClientClick="return('Are you sure you want to delete this record')"
Text="Delete Record" />
However, with GridView
, the approach is similar to that of ASP.NET 1.x in terms of adding a confirmation box before deleting a GridView
row. That is, you have to attach the confirm()
script to the attributes of the delete column. Only with ASP.NET 2.0, you need to place the confirmation script within the RowDataBound
event handler.
<script language="c#" runat="server">
// ...
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//suppose you have a link button column
LinkButton l = (LinkButton)e.Row.FindControl("LinkButton1");
l.Attributes.Add("onclick",
"javascript:return confirm('Are you sure you want to delete
this record?'");
}
}
script>
As an alternative, you can convert the CommandField
to a TemplateField
and add a Button with the onClientClick
property set to confirm()
.
<form id="form1" runat="server">
<asp:SqlDataSource runat="server"
ID="SqlDataSource2"
ConnectionString="..."
SelectCommand="SELECT [CategoryID], [CategoryName],
[Description] FROM [Categories]"
DeleteCommand="Delete from categories where categoryID=@categoryID">
<DeleteParameters>
<asp:Parameter Name=categoryID Type=int16 />
DeleteParameters>
asp:SqlDataSource>
<asp:GridView ID="GridView2" runat=server AutoGenerateColumns="False"
datasourceid="SqlDataSource2" DataKeyNames=CategoryID>
<Columns>
<asp:BoundField DataField="CategoryID"
HeaderText="ID"
readonly=true/>
<asp:BoundField DataField="CategoryName" HeaderText="Name"/>
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:Button ID="deleteButton" runat="server"
CommandName="Delete" Text="Delete"
OnClientClick="return confirm('Are you sure you want
to delete this record?');" />
ItemTemplate>
asp:TemplateField>
Columns>
asp:GridView>
...
3. Maintaining Page Scrolling Position
In ASP 2.0, it is very easy to maintain a web page's scrolling position across postbacks. To achieve this, simply add a page directive at the top of your webpage:
<%@ Page ... MaintainScrollPositionOnPostback="true" %>
However in ASP 1.x, it is not quite so simple, even though ASP.NET 1.x has a Smartnavigation
page directive that supposedly enables you to achieve the same goal. But as noted in many online posts and publications, SmartNavigation
has many known issues and it works only with Internet Explorer 5.5 or later. Several developers wrote some JavaScript code and wrapped the code inside a custom server control to work around the problem. For example, there is an article by Steve Stchur addressing this issue: Maintaining Scroll Position on Postback
ASP.NET 2.0 not only provides ways to simplify some of the most common client-side tasks, it also allows you to write and include your own JavaScript in a web form. There are three ways to do so:
As mentioned above, in ASP.NET 1.x, to include script in a web page, you always have to take two steps:
Page
classIn ASP.NET 2.0, there is a similar approach. However, instead of the Page
class, it is recommended you register the script using the methods exposed by the ClientScript
property of the Page
class. ClientScript
is an instance of a new ASP.NET 2.0 class called ClientScriptManager
. Moreover, ClientScript
has many more new methods to work with JavaScript.
Injecting Script blocks on demand
Script blocks on demand are code that execute only if a code-specific event is triggered on the client side. To inject script blocks on demand, use ClientScript.RegisterClientScriptBlock
. The following example shows how to pop up a new window when the button btnPopUp
is clicked using the RegisterClientScriptBlock
method:
<script runat="server">
protected void btnPopUp_Click(object sender, EventArgs e)
{
//Build a Pop Up JavaScript
//please note the peculiar '/script' in the last line of the script string
//This is to work around the problem that compiler would mistake the
//closing script tag as the outer script closing tag.
//For details, please see
//http://support.microsoft.com/default.aspx?scid=kb;EN-US;827420
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("");
sb.Append("window.open('javascript.htm', 'CustomPopUp',");
sb.Append("'width=200, height=200, menubar=yes, resizable=no');<");
sb.Append("/script>");
//register with ClientScript
//The RegisterStartupScript method is also slightly different
//from ASP.NET 1.x
Type t = this.GetType();
if (!ClientScript.IsClientScriptBlockRegistered(t, "PopupScript"))
ClientScript.RegisterClientScriptBlock(t,"PopupScript", sb.ToString());
}
script>
<form id="form2" runat="server">
<asp:Button ID="btnPopUp" runat="server"
Text="PopUp" OnClick="btnPopUp_Click" />
form>
Startup Script Blocks
Like the Page.RegisterStartupScript
method with ASP.NET 1.x, ASP.NET 2.0 has ClientScript.RegisterStartupScript
to execute JavaScript when the page first loads. The above example could be converted to:
// ...
Type t = this.GetType();
if (!ClientScript.IsStartUpScriptRegistered(t, "PopupScript"))
ClientScript.RegisterStartUpScript(t,"PopupScript", popupScript);
Including JavaScript on the server side
You can also include external JavaScript files via codebehind. Let's say you have a JavaScript file called myJavaScript.js, and you would like include it inside the web form by using the RegisterClientScriptInclude
method, as shown in the following:
ClientScript.RegisterClientScriptInclude("MyScript","MyJavaScript.js")
This piece of code will inject the following JavaScript include in your html code generated by the server:
<script src="MyJavaScript.js" type="text/javascript">script>
Embedding JavaScript in Resources
In ASP.NET 2.0, you can also add your JavaScript or image files or CSS stylesheet as embedded resources. However, to do so, you must create a custom control, add necessary scripts or files to the project, then set the files property of Build Action
as an embedded resources, as illustrated in the following screenshot:
For this article, I borrowed (however simplified) a custom control called AutoComplete Dropdownlist as an example. Briefly, to be able to access the JavaScript in the embedded resource, you need to take two steps: Declare the resource in the control's class file or in the AssemblyInfo.cs
using the syntax:
[assembly: WebResource("{namespace}.{filename}", "{content-type}")]
And in our example, it would be:
[assembly: WebResource("WebControlLibrary1.AutoComplete.js", "text/javascript")]
By doing so, we mark the file as accessible through the WebResource.axd
HTTP handler, then we may retrieve the actual file from the resources of the project's assembly by calling the method GetWebResourceUrl(type, webresource)
.
Now we can inject the JavaScript or other resource file by using the RegisterClientScriptInclude
method.
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.Page.ClientScript.RegisterClientScriptInclude("AutoComplete",
this.Page.ClientScript.GetWebResourceUrl(typeof(AutoCompleteDropDownList),
"WebControlLibrary1.AutoComplete.js"));
}
JavaScript is essential to keep web pages nimble and responsive. While ASP.NET 1.x has been cumbersome working with script, ASP.NET 2.0 has made great enhancements to remedy the limitations. It has made dealing with some of the most common client-side tasks as easy as setting control properties, and has introduced new classes and methods to allow injecting JavaScript into webforms
more flexible.
.NET Framework 3.5 New Features
Faster .NET Framework execution | Base Class Library – New Class Additions | Language Integrated Query (LINQ) |
1. Faster garbage collection 2. Smarter, faster NGen requiring smaller working set RAM 3. 64 bit client improvements 4. ThreadPool performance improvements 5. Security check caching during NGen | 6. BigInteger, HashSet and DateTime2 types 7. NSA Suite ”B” and FIPs compliant cryptography 8. Lightweight Reader/Writer Lock Classes 9. Anonymous and Named Pipes IO Classes 10. Integration with Event Tracing for Windows 11. New Addin hosting model for extensibility | Deep integration of LINQ data-awareness into the programming languages and framework. |
Workflow Enabled Services – Process and Messaging together | Web 2.0 Friendly and AJAX Enabled WCF Services | Visual Studio Developer Tools for WF, WCF and in Visual Studio “Orcas” |
Using workflow to provide for durable and long-running services. New Tools, WF activities and new programming model classes have been added to simplify building workflow-enabled services using WF and WCF. This allows a .NET Framework developer to build business logic for a service using WF and expose messaging from that service using WCF. These improvements not only provide tools for this scenario but they reduce the amount of glue code that was previously required. | Ajax is a web development technique for making asynchronous exchanges of small amounts of data between browser and web service calls from the browser client script to the web server. A programming model is provided for building Ajax style web applications using WCF services. An HTTP programming model is also provided allowing for REST style web services. | Visual Studio”Orcas” has built in tools for web service authoring with WCF and for building workflow enabled software with WF. There are new project templates for WCF services, WF business logic, workflow enabled services, and AJAX services. The templates are conveniently set up to compile and run even before any custom code is added enabling .NET developers to get going quickly. There are also numerous other tools for developing with WF, WCF and WPF. |
More WS-* Standards Support | RSS and ATOM Syndication API | Partial Trust Support for WCF Hosting |
Implementation in WCF of the latest OASIS specifications Web Services Atomic Transaction (WS-AtomicTransaction) 1.1, WS-ReliableMessaging 1.1, WS-SecureCOnversation and Web Services Coordination (WS-Coordination) 1.1. | Applications built using WCF will be able to easily expose syndicated data which can be consumed by an RSS or ATOM reader. | Partial trust on the vlient is provided for ASMX parity focussing mainly on partially trusted WCF applications deployed through click-once. Support is provided for basic HTTP binding provided that the application runs in the Internet zone permissions and have granted the apropriate WebPermission. Secure communication is possible through transport security only. All other features are not available to partially trusted applications including hosting services, duplex communications, non-HTTP transports, WS-* protocols and any WF use. |
Rules Data Improvements | Built-in WPF tools for Visual Studio “Orcas” | Additional WPF Features and Improved Performance |
The rules engine in WF is improved to add support for C# 3.0 extension metods, and for operator overloading . Also the ”new” operator is added to compete the base set of expression types. | The Visual Studio designer for WPF was previously released as a CTP. It is not integrated into the development environment and is significantly improved. | WPF has smoother animations, faster startup and better overall performance. There are also new data types available for data binding with LINQ. Better integration support is now provided for with codename “WPF/E”. |
Cloning C# objects is one of those things that appears easy but is actually quite complicated with many "gotchas." This article describes the most common ways to clone a C# object.
There are two types of object cloning: shallow and deep. A shallow clone copies the references but not the referenced objects. A deep clone copies the referenced objects as well.
Hence, a reference in the original object and the same reference in a shallow-cloned object both point to the same object. Whereas a deep-cloned object contains a copy of everything directly or indirectly referenced by the object. See wikipedia for a detailed explanation.
The ICloneable interface contains a single Clone method, which is used to create a copy of the current object.
public interface ICloneable
{
object Clone();
}
The problem with ICloneable is that the Clone method does not explicitly specify whether it is performing a shallow or deep copy, so callers can never be sure. Hence, there is some discussion about making ICloneable obsolete in the .NET Framework. The MSDN documentation seems to hint that Clone should perform a deep copy, but it is never explicitly stated:
The ICloneable interface contains one member, Clone, which is intended to support cloning beyond that supplied by MemberWiseClone… The MemberwiseClone method creates a shallow copy…
Another disadvantage of ICloneable is that the Clone method returns an object, hence every Clone call requires a cast:
Person joe = new Person();
joe.Name = "Joe Smith";
Person joeClone = (Person)joe.Clone();
One way to avoid the cast is to provide your own type-safe Clone method. Note that you must still provide the ICloneable.Clone method to satisfy the ICloneable interface:
public class Person : ICloneable
{
public string Name;
object ICloneable.Clone()
{
return this.Clone();
}
public Person Clone()
{
return (Person)this.MemberwiseClone();
}
}
Following are some of the more common approaches to clone a C# object:
One way to guarantee that an object will be cloned exactly how you want it is to manually clone every field in the object. The disadvantage to this method is it's tedious and error prone: if you add or change a field in the class, chances are you will forget to update the Clone method. Note that care must be taken to avoid an infinite loop when cloning referenced objects that may refer back to the original object. Here is a simple example that performs a deep copy:
public class Person : ICloneable
{
public string Name;
public Person Spouse;
public object Clone()
{
Person p = new Person();
p.Name = this.Name;
if (this.Spouse != null)
p.Spouse = (Person)this.Spouse.Clone();
return p;
}
}
MemberwiseClone is a protected method in the Object class that creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. For value-type fields, this performs a bit-by-bit copy. For reference-type fields, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object. Note this works for all derived classes, and hence you only need to define the Clone method once in the base class. Here is a simple example:
public class Person : ICloneable
{
public string Name;
public Person Spouse;
public object Clone()
{
return this.MemberwiseClone();
}
}
Cloning by Reflection uses Activator.CreateInstance to create a new object of the same type, then performs a shallow copy of each field using Reflection. The advantage of this method is it's automated and does not need to be adjusted when members are added or removed from the object. Also, it can be written to provide a deep copy. The disadvantage is it uses Reflection, which is slower and not allowed in partial trust environments. Sample code
One of the easiest ways to clone an object is to serialize it and immediately deserialize it into a new object. Like the Reflection approach, the Serialization approach is automated and does not need to be adjusted when members are added or removed from the object. The disadvantage is that serialization can be slower than other methods including Reflection, and all cloned and referenced objects must be marked Serializable. Also, depending on what type of serialization you use (XML, Soap, Binary), private members may not be cloned as desired. Sample code here and here and here.
A fringe solution is to use IL (Intermediate Language) to clone objects. This approach creates a DynamicMethod, gets the ILGenerator, emits code in the method, compiles it to a delegate, and executes the delegate. The delegate is cached so that the IL is generated only the first time and not for each subsequent cloning. Although this approach is faster than Reflection, it is difficult to understand and maintain. Sample code
Havard Stranden created a custom cloning framework using extension methods. The framework creates a deep copy of an object and all referenced objects, no matter how complex the object graph is. The disadvantage is this is a custom framework with no source code (Update: source code now included, see comment below), and it cannot copy objects created from private classes without parameterless constructors. Another problem, which is common to all automated deep copy methods, is that deep copying often requires intelligence to handle special cases (such as unmanaged resources) that cannot be easily automated.
Add a comment