Search

25 October, 2008

The 10 Commandments of Great User Experience Design

Starting a new software development project in the next little while?  Praying and hoping that it goes well?  Are you worrying about all the little software development intricacies like: Making sure you have a proper source control, ensuring you have a continuous integration environment, making sure you have great developers and making sure they are happy?  If you are, you probably haven’t remembered to pay attention to the most important part of the software development process. The User Interface and the User Experience.

While there are literally hundreds of User Experience rules that you could follow, if you simply remember these 10 commandments, you should do just fine!  In fact, I recommend you print them out and put them in every developers office, or cubicle. Believe me..you will praise me in the long run.

  1. Publish your application’s goals and objectives, your “mission statement” if you will.
  2. The less choices you present to the user, the better.  Users get confused rather quickly.
  3. User Interface should remain consistent from screen to screen.
  4. No “Smart Menus” that change depending on how you use the application.  Users hate their application “changing” on them.
  5. Keep the “Noise” to a minimum.  People don’t need to know about the business as usual messages.  Don’t annoy your user.
  6. Avoid acronyms if at all possible. If you must use them, supply a descriptive message right beside it.
  7. Your application must run lean and mean.  As pretty as your interface might be, if the software seems slow, no sale.
  8. Let them explore the application, without fear they will cause a disaster. Undo, Redo, and History features might be a good idea.
  9. Ensure your software works the first time its run.  Configurations can occur later, but out of the box, you should have intelligent defaults.
  10. Have an easy way of allowing your users to provide feedback
Every item on this list is very critical for the success of your project.  Make sure your software development team is always thinking about these things throughout your next project and you should be fairly happy with the outcome of the project.

I find that typically software developers will end up focusing solely on the architecture and technology of the application they working on, and leave the user experience piece as an afterthought.  This can have a huge impact on your timeline, and the happiness of the user’s of your application.  How many software developers out there have been on a project where you worked your buts off for months (if not years), and then went to release something to the users, and they where unimpressed with the application because the team didn’t put enough weight on the user experience?

03 October, 2008

Dictionary VS Hash Table

We all know how useful a hash table can be, but if you are using the .NET Framework 2.0 you should be using a Dictionary instead. A dictionary and a hash table in .NET 2.0 are very similar but with 1 main difference, a dictionary is faster because it does not need to box and unbox the data as a hash table would.

I made a simple program to see just how much faster a dictionary is than a hash table. I ran the test 20 times for each data set and the results were close each time. A GUID as the key and a boolean as the data.

This is the results of the last test for each dataset.

Time in Milliseconds for 100,000 keysDictionaryHash Table
Inserting34.4126476.0970
Reading18.900531.1648
Deleting21.247430.4655

 

Time in Seconds for 10,000,000 keysDictionaryHash Table
Inserting6.570414326.9096540
Reading3.13628915.6670613
Deleting3.46233164.8830676

 

06 August, 2008

Improving Performance with Connection Pooling

Opening a connection is a database-intensive task. It can be one of the slowest operations that you perform in an ASP.NET page. Furthermore, a database has a limited supply of connections, and each connection requires a certain amount of memory overhead (approximately 40 kilobytes per connection).

If you plan to have hundreds of users hitting your Web site simultaneously, the process of opening a database connection for each user can have a severe impact on the performance of your Web site.

Fortunately, you can safely ignore these bad warnings if you take advantage of connection pooling. When database connections are pooled, a set of connections is kept open so that they can be shared among multiple users. When you request a new connection, an active connection is removed from the pool. When you close the connection, the connection is placed back in the pool.

Connection pooling is enabled for both OleDb and SqlClient connections by default.

To take advantage of connection pooling, you must be careful to do two things in your ASP.NET pages. First, you must be careful to use the same exact connection string whenever you open a database connection. Only those connections opened with the same connection string can be placed in the same connection pool. For this reason you should place your connection string in the web.config file and retrieve it from this file whenever you need to open a connection.

To take advantage of connection pooling in your ASP.NET pages, you also must be careful to explicitly close whatever connection you open as quickly as possible. If you do not explicitly close a connection with the Close() method, the connection is never added back to the connection pool.

Connection pooling options that you can add to the SQL Server connection string:
  • Connection Lifetime— Destroys a connection after a certain number of seconds. The default value is 0, which indicates that connections should never be destroyed.
  • Connection Reset— Indicates whether connections should be reset when they are returned to the pool. The default value is true.
  • Enlist— Indicates whether a connection should be automatically enlisted in the current transaction context. The default value is true.
  • Max Pool Size— The maximum number of connections allowed in a single connection pool. The default value is 100.
  • Min Pool Size— The minimum number of connections allowed in a single connection pool. The default value is 0.
  • Pooling— Determines whether connection pooling is enabled or disabled. The default value is true.

SQL Injection Problem

SQL injection is a strategy often taken by hackers for attacking databases.

Example1:
An ASP page asks the user for a name and a password, and then sends the following string to the database:
SELECT FROM users WHERE username = 'whatever' AND password = 'mypassword'

It seems safe, but it isn't. A user might enter something like this as her user name:
' OR 1>0 --

When this is plugged into the SQL statement, the result looks like this:
SELECT FROM users WHERE username = '' OR 1>0 -- AND password = ''

This injection comments out the password portion of the statement. It results in a list of all the names in the users table, so any user could get into your system.

The easiest way to prevent this sort of injection is to parse the SQL string and remove any occurrences of "--" before passing the statement.

Example 2:
You also have to beware of injections that contain semicolons because semicolons delimit SQL statements. Think about the implications of a user name like this:
' OR 1>0 ; DELETE Customers ; --

There are numerous ways a malicious user might penetrate your system using SQL injection and various defenses, but the simplest approach is to avoid dynamic SQL. Instead, use stored procedures everywhere.

Thanks to the way SQL passes parameters, injections such as those above will produce errors, and the stored procedure will not execute.

01 August, 2008

Running an exe or program as SQL Server Job

This can be achieved by SQL Server Agent which is a Windows service to run scheduled adminstrative tasks or commonly know as jobs. SQL Server agent uses SQL Server t ostore job information. A job consists of steps which can be set using steps wizard during job scheduling.

Job Scheduling process:
  • Connect to the SQL Server where you want to schedule your job.
  • Check if SQL Server Agent (you can find it at the bottom most entity) is running, if not run it and set it to run automatic.
  • Right Click SQL Server Agent. Select New -> Job. This will open a wizard to schedule a new job.
  • Select Steps from options given on the left side of wizard. This is the main place to set your exe\program as a running step. Give some name to this step, Select Operating System (cmd) for the Type and give the full path of exe in Text box for Command. Below is a sample step set up for running test.exe.
  • Now Select the job schedules option from left to set the frequency. Give some name to schedule, selection other options as shown in the figure below.
  • If you want you can set optional Alerts and notification (using SQL notification services) to send out email in case any things fails, succeeds or at any specific event.
  • The targets option set the DB to look at or put data in. It should commonly be the localhost but you can set a remote SQL Server too here in case you have some DB interaction but then make sure that the account which you are using should have access to the remote server.

Your job is now scheduled to run everyday test.exe. just to make sure that everything run properly go to Agent -> Jobs -> NEW_JOB (the one you just created), right click NEW_JOB and select “start job at step”. This will run the job instantly for you and show the status if the job run successfully or failed.

So now you finally done.



24 July, 2008

Asp.Net Worker Process Recycling

If a Web application contains code that causes problems, and you cannot easily rewrite the code, it might be useful to limit the extent of the problems by periodically recycling the worker process that services the application. You can accomplish this by using what is known as Worker Process Recycling. Worker process recycling is the replacing of the instance of the application in memory. IIS 6.0 can automatically recycle worker processes by restarting the worker process, or worker processes, that are assigned to an application pool. This helps keep problematic applications running smoothly, and minimizes problems such as memory leaks. You can trigger the recycling of the worker processes assigned to an application pool by using worker process recycling methods that are based on elapsed time, the number of Hypertext Transfer Protocol (HTTP) requests, a set time of day, and two kinds of memory consumption, in addition to recycling on demand.

To configure all the above settings, go to the Properties window of the application pool in which your Web application is running using the IIS manager. Using the Recycling, Performance, and Health tabs in the Properties window, you can specify values for the above settings. Navigating to the Performance tab in the Properties dialog box of the DemoAppPool results in the following output.



When you set the recycling of worker processes using IIS manager, you also need to take the state management strategy of your ASP.NET application into consideration. Because every time the worker process is recycled, the ASP.NET state information will be lost rendering the application in an invalid state. One alternative to overcome this issue is to maintain state data external to the worker process, such as in a database. However, moving data to an external database to allow recycling can affect server performance in the following two ways:

  • Performance is reduced because of the added data management that is needed to move the data between the application and the database.
  • Recycling flushes any in-process data caches, so the caches need to be rebuilt.

If you have an application pool with applications that depend on state data, you must decide whether or not to recycle the worker processes that are assigned to that application pool. If you store state in the same process as that of IIS, and you don't want the state information to be lost, you must not recycle a worker process using the application pool configuration settings.

22 July, 2008

Encryption Sections of Web.config

Configuration files are just great ; they let you configure the website .It's a great place to store the information which you are going to be using throughout the application and which is not changing.

You can easily encrypt sections of web.config in ASP.NET 2.0. In the code below I have encrypted the ConnectionStrings section of web.config.

Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
ConfigurationSection configSection = config.GetSection("connectionStrings");

if (configSection.SectionInformation.IsProtected)
{
configSection.SectionInformation.UnprotectSection();
config.Save();
}
else
{
configSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
config.Save();
}

.NET Framework 2.0 introduces a protected configuration feature that you can use to encrypt sensitive configuration file data by using a command line tool. The following two protected configuration providers are provided although you can also implement custom providers.
  • RSAProtectedConfigurationProvider : This is the default provider and uses the RSA public key encryption to encrypt and decrypt data.
  • DPAPIProtectedConfigurationProvider : This provider uses the Windows Data Protection API (DPAPI) to encrypt and decrypt data.

You can also writing connection string dynamically:

Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
ConnectionStringsSection conSection = (ConnectionStringsSection)config.GetSection("connectionStrings");
conSection.ConnectionStrings["SQLConnectionString"].ConnectionString = "NewConnectionString";
config.Save();

[Please note that when you write to a web.config file the application restarts which means all the session and application variables are lost.]

26 June, 2008

Spy on Your Web Host: Checking Uptime

Your host promises 99.999% uptime, but are they really delivering? Unless you're either checking every couple of seconds, or dishing out on some monitoring service, you really don't have much of an idea.

ASP.NET Web pages served up through IIS are delivered through an ASP.NET "worker process" (aspnet_wp.exe). It's this file that executes your code and puts all the ASP.NET pieces together. If we could access this worker process, we may be able to look at how long it had been running, its current state—and perhaps even a history, showing previous instantiations of the worker process.

Dim strReport As String
Dim objInfo As ProcessInfo = _
ProcessModelInfo.GetCurrentProcessInfo
' Get time information
strReport = "ASP.NET was started at " & objInfo.StartTime.ToString & ". " & "It has been running for " & objInfo.Age.Days & " days, " & objInfo.Age.Hours & " hours and " & objInfo.Age.Minutes & " minutes. "

Response.Write(strReport)
' Get other info
strReport = "The process ID is " & objInfo.ProcessID & ". " & "Current status is " & objInfo.Status.ToString & ". " & "Peak memory used was " & objInfo.PeakMemoryUsed & ". " & "Request count is currently " & objInfo.RequestCount & "."

Response.Write(strReport)

What we're doing here is retrieving a ProcessInfo object containing information about the current worker process. This is then formulated into a string using key properties and spurted out to the user, through Response.Write. Try it out—you'll be given an instant server status report.

The ProcessModelInfo class also has a GetHistory method, allowing you to retrieve information about previous instances of the aspnet_wp.exe process. It returns an array of ProcessInfo objects. Either use a For...Next loop to retrieve this information, or bind direct to a Grid.

There's also a technique for retrieving the amount of time your actual server has been running (not just the ASP.NET worker process). Simply nab the TickCount from the Environment class, which lists the number of milliseconds the machine has been running. After that, either perform a few simple calculations—or, slightly easier, convert it into a period of time (a TimeSpan object), then retrieve the appropriate properties. Here's my snippet of code that does exactly that:

Dim tsAge As TimeSpan = TimeSpan.FromMilliseconds(Environment.TickCount)
Dim intDaysUp As Integer = tsAge.Days
Dim intHoursUp As Integer = tsAge.Hours
Dim intMinsUp As Integer = tsAge.Minutes
Response.Write("The server has been up " & intDaysUp & " days, " & intHoursUp & " hours and " & intMinsUp & " minutes.")




Caption: ASP.NET only been running for 13 minutes? Sounds dodgy. Change your host.

.Net Tips and Tricks (Part -V)

Force Button Click by Pressing Enter Key
Sometimes, you will notice, that, in an ASP.Net form, depending on the circumstances, pressing the 'Enter' key to submit the form does not work.To force this to happen for a particular button on your page, just put this in the Page_Load routine:
Page.RegisterHiddenField("__EVENTTARGET", "button1")
Then, change 'button1' to the ID of your particular button. Understand, of course, if your cursor is inside of a MultiLine textbox, the default action of the enter key is to create a new line in the textbox, so, if this basically works anywhere outside of that scenario.

Select Specific DropDownList Item
With a dropdown list - you can dynamically select items in the list with a sort of 'built-in' find routine.To select a certain item, based on the Value of the item in the list:
DropDownList.SelectedIndex = DropDownList.Items.IndexOf(DropDownList.Items.FindByValue(YourValueHere))
To select a certain item, based on the Text of the item in the list:
DropDownList.SelectedIndex = DropDownList.Items.IndexOf(DropDownList.Items.FindByText("YourTextHere"))
OR - you can do it this way:
DropDownList.Items.FindByText("TextYouAreLookingFor").Selected = true
or, using the value of the item
DropDownList.Items.FindByValue("ValueYouAreLookingFor").Selected = true

ASP.Net Server Controls Not Showing on pages
It's possible that ASP.Net is not registered correctly on your system.Try running aspnet_regiis from the command prompt.Here's the default location:
C:\[Windows Folder]\Microsoft.NET\Framework\[ASP.Net Version#]\ aspnet_regiis.exe -i
Windows Server 2003, you must use aspnet_regiis -i -enable. This is because of the "Web Service Extensions" feature in IIS 6
(if you install VS.NET or the framework without IIS installed, and then go back in and install IIS afterwards, you have to re-register so that ASP.NET 'hooks' into IIS properly.")

Make a Horizontal Rule Visible or Invisible
If you want to refer to a Horizontal rule in coding, to make it visible or invisible, just use the runat=Server designation, along with an ID and you're ready to go:
[hr id="rule" visible="true" runat="server"/]

Select Specific ListBox Item
If you don't know the exact index number in the list of listbox items (listbox1.selectedindex=x), then you can find an item and select it by using the Value of the item:
ListBox1.Items.FindByValue(MyValue).Selected = true
If you don't know theValue of the item, but you know the text, you can find and select the item using the Text of the item:
ListBox1.Items.FindByText("TextYouAreLookingFor").Selected = true

List all Tables in an MS Access Database
However you decide to display the list of tables from a particular MS Access Database, just create your connection and display code in the same way you would normally do it.
The only change would be your SQL statement. Structure it this way:
SELECT [Name] FROM MSysObjects WHERE [Type] = 1

Javascript - Delete Textbox text onFocus
Let's say you have an ASP.Net TextBox server control that has the text:
"Enter Fax #"
Then, you want the text to disappear when the user clicks inside the TextBox - - here is a very simple solution.
In the Page_Load event, put:
txtFax.Attributes("OnFocus")="document.formName.txtFax.value='';"

.Net Tips and Tricks (Part -IV)

Numeric-Only Textboxes
If you haven't heard of the built in ASP.Net Validator controls, it's time to learn. There are several, but, for this case, you would use a Regular Expression Validator. The Regular Expression for making sure only numeric data is inserted into the textbox is:
^([0-9]*\d*\d{1}?\d*)$
You'd use it in a Regular Expression Validator, in conjunction with an ASP.Net Textbox, like this:
[asp:TextBox id="txtNumber" Runat="server" /]
[asp:RegularExpressionValidator ID="vldNumber" ControlToValidate="txtNumber" Display="Dynamic" ErrorMessage="Not a number" ValidationExpression="(^([0-9]*\d*\d{1}?\d*)$)" Runat="server"/]

Get the Last Write Time of File
In order to get the last time a file (like an MS Access database, or any other file) was written, you can do the following: Use/import the System.IO namespace, then
Dim sFileWriteTime as File
Label1.Text=sFileWriteTime.GetLastWriteTime(Server.MapPath ("/path/yourMDB.mdb"))

Find Specific Field in DataSet
Sometimes, when we fill DataSet from a Query, we need to get a particular item in one of the DataTable fields for later use. In order to find a particular item, we can use the field name from the database like this, and assign it to a variable:
sOrderNum = Ds.Tables[0].Rows[0]["ordnum"]
We'd just need to have created the variable globally, then, we can use that variable (sOrderNum) easily, anywhere in the page now.

MS Access Update Problems with Parameters
A very common problem, using parameters with MS Access, in ASP.Net is that it does not update the database, but also, it doesn't return an error. The problem, most likely, is that the parameters are not in the same order as the SQL statement. Remember to put the list of parameters in the same order as they hold sql statement, including any parameters in the Clause(s) at the end of the statement.

Check for Null before inserting into Database
Here's a function to ensure a Null value gets inserted into the database.
Function CheckForNULL(strStringToCheck)
if len(trim(strStringToCheck)) = 0 then
CheckForNULL =dbNull.Value
else
CheckForNULL = strStringToCheck
end if
end function
If you have a DateTime field, without a function like this, a default date will be entered (ie 1/1/1900 12:00:00 AM), instead of null, when your insert is executed.

How to Align text in the TextBox Server Control
First, in your StyleSheet (either inline or external), create a class.
For the sake of this tip, we'll call it 'txtAlign', but the name doesn't matter.
Then, add your alignment needs to the class: text-align: right;
Lastly, inside the TextBox Server Control on your page, use the CSSClass property of the textbox to assign the CSS value to the textbox:CSSClass="txtAlign"

How to set focus on an ASP.Net TextBox Control when the page loads
Two things:
1. Give your BODY Tag and ID and include 'Runat=Server'(like - - [body id="bdyMain" runat="Server"])
2. In the Page_Load event:
if not Page.IsPostBack then
bdyMain.attributes("onload")="document.form1.TextBox1.focus();"
end if

How To work with TimeSpan Class
Dim adate As DateTime = DateTime.Parse("06/24/2008")
Dim bdate As DateTime = DateTime.Parse("06/28/2008")
Dim ts As New TimeSpan(bdate.Ticks - adate.Ticks)
Response.Write(ts.TotalDays & " ")
Response.Write(ts.TotalHours & ":" & ts.TotalMinutes & ":" & ts.TotalSeconds & ":" & ts.TotalMilliseconds)

How to Compare Time
Dim t1 As String = DateTime.Parse("4:30 PM").ToString("t")
Dim t2 As String = DateTime.Now.ToString("t")
If DateTime.Compare(t1, t2) <>
Response.Write(t1.ToString() & " is <>
Else
Response.Write(t1.ToString() & " is > than " & t2.ToString())
End If

Loop through all the textbox controls on the ASP.NET Page
You can loop through all the textbox controls on ASP.NET Page using this code.
private void LoopTextBoxes (Control parent)
{
foreach (Control c in parent.Controls)
{
TextBox tb = c as TextBox;

if (tb != null)
//Do something with the TextBox
}
}
And you can start the looping by calling:
LoopTextBoxes(Page);


Disabling a Button Until Processing is Complete
Here's the scenario - let's say you have an Insert subroutine, called 'doInsert'. You want to immediately disable the Submit button, so that the end-user won't click it multiple times, therefore, submitting the same data multiple times.
For this, use a regular HTML button, including a Runat="server" and an 'OnServerClick' event designation - like this:
[INPUT id="Button1" onclick="document.form1.Button1.disabled=true;" type="button" value="Submit - Insert Data" name="Button1" runat="server" onserverclick="doInsert"]
Then, in the very last line of the 'doInsert' subroutine, add this line:
Button1.Disabled=false

25 June, 2008

.Net Tips and Tricks (Part -III)

Gridview Sorting - Only Certain Columns
To allow sorting on only certain columns in a Gridview, set the AllowSorting Property to True, but, for those columns you do NOT want to be sorted, using BoundFields, or TemplateFields, remove the SortExpression property.

Why is my button event firing twice?
The most common reason for double click events are situations in which the button markup includes an OnClick event, AND, the event handler (in your code) also has a 'Handles' statement, at the end of the event handler signature - -

Gridview Paging without a Datasource Control
If you are populating your Gridview with code, and not through a DataSource control, to be able to add paging, merely add a PageIndexChanging event for the Gridview:
Protected Sub YourGridview_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs)
YourGridview.PageIndex = e.NewPageIndex
YourGridview.DataBind()
End Sub

Templates - the Answer to a Consistent Look and Feel
Let's say you have a company, and you have several websites within that company, but you need to have a consistent look and feel for each of them.Create a website with the bare minimum, that you want to look the same in all websites, with Themes, navigation, and whatever else you want.
Then, in VS.Net 2005, click File/Export Template. That's all there is to it. The next time you want a website to look like this template, just click File/New, and choose your template (which will be under 'My Templates'

Using Response object in a Class
If you try this, straight away, you will probably receive an error message, telling you the Response object is not available in this context.
So, in order to get rid of the error message, Import System.Web, and then, change :
Response.(whatever)
to
HttpContext.Current.Response.(whatever)

Add 'Select' feature to existing Button/Imagebutton in TemplateField
If you already have any kind of button, whether it be a plain button, LinkButton, or Imagebutton, in a TemplateField, within a GridView, you can add 'Select' features to it, just as if you had added a 'Select' column.
All you need to do is add 'Select' to the CommandName property. Then, anything you could do with the Select CommandField, you can do with your own TemplateField.

Force TextBox Values to Capital Letters whenever user types(Simple way)
Create a css class with the following definition and apply the cssclass to the Textbox.
.MakeCapsStyle{text-transform: uppercase;}
[asp:textbox id="id" runat="server" cssclass="MakeCapsStyle" /]

Two Databound Fields in Gridview column
Boundfields are great in the Gridview, but they do have their limitations. One is that it only has room for one bound field. So, what do you do when you want two or data fields (like First and Last names) returned to the same column?
Turn the BoundField into a TemplateField, with a label in it:
[asp:TemplateField]
[ItemTemplate]
[asp:Label ID="lblname" runat="server" Text='[%# Eval("Lname") +", "+ Eval("Fname") %' /]
[/ItemTemplate]
[/asp:TemplateField]

Quick and Dirty - Clear Gridview
If you need to completely clear a Gridview quickly, create a sub like this:
Protected Sub ClearGrid(ByVal gv As GridView)
gv.DataSource = Nothing gv.DataSourceID = Nothing gv.DataBind()
End Sub
Then, you can use it by using your Gridview ID:
ClearGrid("YourGridViewID")

Nest Master pages easily
Let's say your scenario is that you want a Master page for your business's website. However, inside that 'shell', you also want a certain design for each department of the business. All you need to do, is create the second 'Department' Master page. Then, inside the Master Directive, include a reference back to the Business Master:
[%@ Master Language="VB" MasterPageFile="~/Business.master" .....
Also, be sure to use different ContentPlaceholder ids, and remember the one caveat - if you're using Nested Masters inside VS.Net 2005, you'll need to only use the html view, since the design view does not support nesting master pages.

Server.Transfer Vs. Response.Redirect
Server.Transfer processes the page from one page directly to the next page without making a round-trip back to the client's browser. This way is faster, with a little less overhead on the server. However, it does NOT update the clients url history list or current url.
Response.Redirect, as expected, is used to redirect the user's browser to another page or site. It DOES perform a trip back to the client where the client's browser is actually redirected to the new page. The browser history list IS updated to reflect the new address.

DataFormatString does not work in Boundfield
The new Gridview control in v2.0 take over the formatting of items in the BoundFields. Therefore, using a DataFormatString by itself won't work. To change the format to, let's say, Currency, we'd need to, not only set the DataFormatString="{0:c}", but we'd need to make use of the HTMLEncode property, setting it to 'False'

Assigning ASP.Net variables to Javascript
Scenario:You have an ASP.Net variable called sCustState, that you also want to use in a Javascript function. Here's how you do make it work, within Javascript, assigning it to a Javascript variable.
var sstate;
sstate='<%#sCustState %>';

Adding a Print Button with Javascript
If you'd like to use an ASP.Net button for printing, all you need to do is :
Add this line to the Page_Load event
btnPrint.Attributes("onClick") ="javascript:window.print();"
Add a button to the page called 'btnPrint'.
Technically, that's it, but, let's say you want to do something a little fancier, using DotNet. Then, add a subroutine (let's call it 'DoPrint'):
Sub doPrint(Source as Object, E as EventArgs)
lblResults.visible="True"
lblResults.text="Page has successfully been sent to the printer!"
End Sub
Then, add a direction to this sub, in the button's tag:
onServerclick="doPrint"

23 June, 2008

Performance Tips for ASP.NET Applications

Cache Aggressively
When designing an app using ASP.NET, make sure you design with an eye on caching. On server versions of the OS, you have a lot of options for tweaking the use of caches on the server and client side. There are several features and tools in ASP that you can make use of to gain performance.
Output Caching—Stores the static result of an ASP request. Specified using the @% OutputCache % directive:
  • Duration—Time item exists in the cache
  • VaryByParam—Varies cache entries by Get/Post params
  • VaryByHeader—Varies cache entries by Http header
  • VaryByCustom—Varies cache entries by browser
  • Override to vary by whatever you want

Fragment Caching—When it is not possible to store an entire page (privacy, personalization, dynamic content), you can use fragment caching to store parts of it for quicker retrieval later.
a) VaryByControl—Varies the cached items by values of a control.

Cache API—Provides extremely fine granularity for caching by keeping a hashtable of cached objects in memory (System.web.UI.caching). It also:

  • Includes Dependencies (key, file, time)
  • Automatically expires unused items
  • Supports Callbacks

Caching intelligently can give you excellent performance, and it's important to think about what kind of caching you need. Imagine a complex e-commerce site with several static pages for login, and then a slew of dynamically-generated pages containing images and text. You might want to use Output Caching for those login pages, and then Fragment Caching for the dynamic pages. A toolbar, for example, could be cached as a fragment. For even better performance, you could cache commonly used images and boilerplate text that appear frequently on the site using the Cache API.

Use Session State Only If You Need To

One extremely powerful feature of ASP.NET is its ability to store session state for users, such as a shopping cart on an e-commerce site or a browser history. Since this is on by default, you pay the cost in memory even if you don't use it. If you're not using Session State, turn it off and save yourself the overhead by adding @% EnabledSessionState = false % to your asp.

For pages that only read session state, you can choose EnabledSessionState=readonly. This carries less overhead than full read/write session state, and is useful when you need only part of the functionality and don't want to pay for the write capabilities.

Use View State Only If You Need To

An example of View State might be a long form that users must fill out: if they click Back in their browser and then return, the form will remain filled. When this functionality isn't used, this state eats up memory and performance. Perhaps the largest performance drain here is that a round-trip signal must be sent across the network each time the page is loaded to update and verify the cache. Since it is on by default, you will need to specify that you do not want to use View State with @% EnabledViewState = false %.

Batch Compile

Always batch compile before deploying a large page into the Web. This can be initiated by doing one request to a page per directory and waiting until the CPU idles again. This prevents the Web server from being bogged down with compilations while also trying to serve out pages.

Avoid the Autoeventwireup Feature

Instead of relying on autoeventwireup, override the events from Page. For example, instead of writing a Page_Load() method, try overloading the public void OnLoad() method. This allows the run time from having to do a CreateDelegate() for every page.

protected override void OnLoad(EventArgs e)
{
Response.Write("Page Load method Over ridden");
}

Use the Optimal Authentication Procedure

There are several different ways to authenticate a user and some of more expensive than others (in order of increasing cost: None, Windows, Forms, Passport). Make sure you use the cheapest one that best fits your needs.

Use Stored Procedures Whenever Possible

Stored procedures are highly optimized tools that result in excellent performance when used effectively. Set up stored procedures to handle inserts, updates, and deletes with the data adapter. Stored procedures do not have to be interpreted, compiled or even transmitted from the client, and cut down on both network traffic and server overhead. Be sure to use CommandType.StoredProcedure instead of CommandType.Text

Use StringBuilder for Complex String Manipulation

When a string is modified, the run time will create a new string and return it, leaving the original to be garbage collected. Most of the time this is a fast and simple way to do it, but when a string is being modified repeatedly it begins to be a burden on performance: all of those allocations eventually get expensive.

Minimize the Use of Format()

When you can, use toString() instead of format(). In most cases, it will provide you with the functionality you need, with much less overhead.

Optimize Assignments

Use exp += val instead of exp = exp + val. Since exp can be arbitrarily complex, this can result in lots of unnecessary work. This forces the JIT to evaluate both copies of exp, and many times this is not needed. The first statement can be optimized far better than the second, since the JIT can avoid evaluating the exp twice.

Keep Your Datasets Lean

Only put the records you need into the dataset. Remember that the dataset stores all of its data in memory, and that the more data you request, the longer it will take to transmit across the wire.

Limit ASP.NET Server Controls

Exceptions and session state impose overhead. Surprise—so do ASP.NET server controls. They require server-side support, which leads to communication between your server and the client to support the control, and resource consumption on the server. Avoid the temptation to drop the server control onto your form and forget about it. In fact, you might be better off with a regular HTML control. Use the server control only if you plan to control the properties of a control programmatically, use view state to hold data values of the control, or handle server-side events generated by the control.

Use Page.IsPostBack

You need to take a series of steps when your page loads for the first time to perform setup formatting on the page or initialize data. However, you don't need to keep reinventing this wheel the next time a page is requested—and the next and the next. Avoid initializing the data again on the postback.

13 June, 2008

.Net Tips and Tricks (Part -II)

How to form Color Picker in ASP.NET
[Click to enlarge]

Make sure to Import the System.Reflections namespace, as well as the System.Drawing namespace, for this example

Prevent caching of webform in Asp.net

private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetAllowResponseInBrowserHistory(false);
}
}

ASP.Net Server Controls Not Showing on pages

Try running aspnet_regiis from the command prompt. Here's the default location: C:\WINNT\Microsoft.NET\Framework\<>\aspnet_regiis.exe -i

Currently logged in user

To get the user ID of the user who is currently logged in, you would get it using this: System.Web.HttpContext.Current.User.Identity.Name

Get windows Identity(win auth)

System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();

Disabling a Button Until Processing is Complete

Here's the scenario - let's say you have an Insert subroutine, called 'doInsert'. You want to immediately disable the Submit button, so that the end-user won't click it multiple times, therefore, submitting the same data multiple times.

For this, use a regular HTML button, including a Runat="server" and an 'OnServerClick' event designation - like this:

INPUT id="Button1" onclick="document.form1.Button1.disabled=true;" type="button" value="Submit - Insert Data" name="Button1" runat="server" onserverclick="doInsert"

Then, in the very last line of the 'doInsert' subroutine, add this line: Button1.enabled="True"

Adding a MailTo Link inside a DataGrid

Suppose you have a database table which contains an email field, and you'd like to display that field, as well as others in a DataGrid. Let's go one step further - - let's say you'd like to display that email field as a clickable MailTo link. One way that this can be easily be done using TemplateColumns. First, you create your DataGrid start and end tags. Then, inside these tags, you include 'Columns' start and end tags. That's where you put your TemplateColumn. Here's how to do it

Use Path.GetRandomFileName() or Path.GetTempFileName() when working with temp files
Do not reinvent function for generating unique name for temporary files. Use one of the existing methods:
*** System.IO.Path.GetTempFileName() - use this method if you want to create temporary file in user's temp folder.
*** System.IO.Path.GetRandomFileName() - use this method if you just want to generate unique file name.


Popup Window Code

You can use Javascript to do so. e.g.

input type="Button" Value="Open New" onclick="Javascript:window.open('webform1.aspx');"

Uploading Large Size File
The default file size limit for the FileUpload control in ASP.Net is 4Mb. To get around this, in the HTTPRuntime section of the Web.config file, you can set the 'maxRequestLength' (in kb):
[system.web]
[httpRuntime maxRequestLength="1500000" /]
[/system.web]

How to Register User Controls and Custom Controls in Web.config

ASP.NET 2.0 makes control declarations much cleaner and easier to manage. Instead of duplicating them on all your pages, just declare them once within the new pages->controls section with the web.config file of your application:

Once you register the controls within the web.config file, you can then just use the controls on any page, master-page or user control on your site like so (no registration directives required):
[html]
[body]
[form id="form1" runat="server]
[scott:header ID="MyHeader" runat="server" /]
[/form]
[/body]
[/html]





.Net Tips and Tricks (Part -I)

Use "App_Offline.htm" feature while updating a web site
"App_Offline.htm" feature provides a super convenient way to bring down an ASP.NET application while you updating a lot of content or making big changes to the site where you want to ensure that no users are accessing the application until all changes are done. The way app_offline.htm works is that you place this file in the root of the application. When ASP.NET sees it, it will shut-down the app-domain for the application and instead send back the contents of the app_offline.htm file in response to all new dynamic requests for the application. When you are done updating the site, just delete the file and it will come back online.

You have developed and deployed a web application on a web server. When users are making a request to the default.aspx file on the web server from their browser, they are being prompted to download the default.aspx file on their computer. What could be the problem.
Problem with aspnet_isapi.dll This behavior means that although the request is going to the IIS, it is not being executed by the asp.net worker process because IIS is not sure what to do with this file. This is because the aspnet_isapi.dll is either not present or IIS is not pointing to aspnet_isapi.dll.

Password matching regular expression
Password must be at least 4 characters, no more than 8 characters, and must include at least one upper case letter, one lower case letter, and one numeric digit. ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$

Make Window Fit any Resolution


Quickly move to matching brace in Visual Studio
Just press Ctrl+] and VS.NET will take you to the matching brace. It also will take you to the matching comment, region or quote depending on what is at the cursor now.

Incremental search in Visual Studio.
Press Ctrl+I.
Start typing the text you are searching for. (Note: you'll see the cursor jump to the first match, highlighting the current search string.)
Press Ctrl+I again to jump to the next occurrence of the search string.
To stop search, press Esc.
Advanced tip: Press Ctrl+Shift+I to search backwards

Clear all text boxes in ASP.Net


This will clear EVERYTHING from the textboxes - even if you had them pre-populated with data. A simple way to just reset it to the condition at Page_Load time, just do this in the Reset SubRoutine: Server.Transfer("YourPageName.aspx")

How to rotate a Label Text?

[asp:Label id="Label1" style="writing-mode:tb-rl" runat="server"]Label[/asp:Label]

Get Row Index with Gridview Select Button
When you autoGenerate a Select button with a Gridview, to find the RowIndex for that particular row, you can use the SelectedIndexChanged Event. Inside that event, try something like this (with a label called 'Label1':
Dim row As GridViewRow = MyGridView.SelectedRow
Dim intRow as Integer=Row.RowIndex
label1.text=intRow.ToString

Auto select Gridview Row when Editing

Let's say you have an editable Gridview, and you'd like to change the backcolor of the row you're editing, when you click the 'Edit' link for that row. It's very simple, and it's done in the Gridview's RowEditing Event.

First, you must set the SelectedIndex of the Gridview to the row you're editing:
YourGridviewID.SelectedIndex = e.NewEditIndex

And, lastly, you must change the backcolor:
YourGridviewID.SelectedRow.BackColor = Drawing.Color.Pink

You can, of course, accomplish any other row formatting options here, also.
Full code and Subroutine is here:
Protected Sub YourGridviewID_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles YourGridviewID.RowEditing

YourGridviewID.SelectedIndex = e.NewEditIndex

YourGridviewID.SelectedRow.BackColor = Drawing.Color.Pink

End Sub

System.Configuration Namespace

The heart of the new .NET 2.0 configuration gem is the System.Configuration namespace. By default, this namespace is available when the System.dll assembly is referenced. It includes all of the configuration features of .NET 1.1, including the old ConfigurationSettings class (now deprecated in .NET 2.0). To gain access to all of the new .NET 2.0 configuration features, however, you must add a reference to the System.Configuration.dll assembly. It is in this assembly that you will find the core of the new configuration system, the ConfigurationManager static class.

The ConfigurationManager class is a globally accessible doorway to an application's configuration. Since the class is static, all of its members are also static. This makes reading configuration such as AppSettings, ConnectionStrings and custom configuration sections a breeze. While this is similar to the ConfigurationSettings class, it also provides several new features that allow more secure access to an application's configuration. These new features also allow configuration settings to be saved to any configuration section: custom or otherwise.

Beyond the ConfigurationManager class lies the life-blood of custom configuration sections. The following outlines the base classes available to help you write your own configuration object model. In addition to a set of base classes is a set of validators that can be used to ensure the accuracy of your custom configuration. Also, in the event that your needs are simple enough, a few pre-made configuration sections are available.

The base types
  • ConfigurationSection - The base class of all configuration sections
  • ConfigurationSectionCollection - The base class of a collection of configuration sections
  • ConfigurationSectionGroup - The base class of a configuration section group
  • ConfigurationSectionGroupCollection - The base class of a collection of configuration section groups
  • ConfigurationElement - The base class of a configuration element
  • ConfigurationElementCollection - The base class of a collection of configuration elements
  • ConfigurationConverterBase - The base class of a custom converter
  • ConfigurationValidatorBase - The base class of a custom validator

The support types

  • ConfigurationManager - Allows global access to all of an application's configuration
  • Configuration - A class that represents an application's configuration
  • ConfigurationProperty - A class that represents a single configuration property
  • ConfigurationPropertyAttribute - An attribute class that supports declarative definition of configuration
  • ConfigurationPropertyCollection - A collection of configuration properties
  • ConfigurationPropertyOptions - Enumeration of possible configuration property options

The validation types

  • CallbackValidator - Allows dynamic validation of a configuration value
  • CallbackValidatorAttribute - Attribute class for declaratively applying callback validators
  • IntegerValidator - Allows validation of an integer (Int32) configuration value
  • IntegerValidatorAttribute - Attribute class for declaratively applying integer validators
  • LongValidator - Allows validation of a long (Int64) configuration value
  • LongValidatorAttribute - Attribute class for declaratively applying long validators
  • PositiveTimeSpanValidator - Allows validation of a positive time span configuration value
  • PositiveTimeSpanValidatorAttribute - Attribute class for declaratively applying positive time span validators
  • RegexStringValidator - Allows validation of a string configuration value with a regular expression
  • RegexStringValidatorAttribute - Attribute class for declaratively applying regex validators
  • StringValidator - Allows validation of a string configuration value
  • StringValidatorAttribute - Attribute class for declaratively applying string validators
  • SubclassTypeValidator - Allows validation that a configuration value derives from a given type
  • SubclassTypeValidatorAttribute - Attribute class for declaratively applying subclass type validators
  • TimeSpanValidator - Allows validation of a time span configuration value
  • TimeSpanValidatorAttribute - Attribute class for declaratively applying time span validators

The converter types

  • CommaDelimitedStringCollectionConverter - Converts a comma-delimited value to/from CommaDelimitedStringCollection
  • GenericEnumConverter - Converts between a string and an enumerated type
  • InfiniteIntConverter - Converts between a string and the standard infinite or integer value
  • InfiniteTimeSpanConverter - Converts between a string and the standard infinite TimeSpan value
  • TimeSpanMinutesConverter - Converts to and from a time span expressed in minutes
  • TimeSpanMinutesOrInfiniteConverter - Converts to and from a time span expressed in minutes or infinite
  • TimeSpanSecondsConverter - Converts to and from a time span expressed in seconds
  • TimeSpanSecondsOrInfiniteConverter - Converts to and from a time span expressed in seconds or infinite
  • TypeNameConverter - Converts between a Type object and the string representation of that type
  • WhiteSpaceTrimStringConverter - Converts a string to its canonical format, i.e. white space trimmed from front and back

Pre-made configuration sections

  • AppSettingsSection - This provides the well-known configuration section
  • ConnectionStringsSection - This provides the new configuration section
  • ProtectedConfigurationSection - This provides an encrypted configuration section
  • IgnoreSection - Special configuration section wrapper that is ignored by the configuration parser

Premade configuration collections

  • CommaDelimitedStringCollection - Used in conjunction with CommaDelimitedStringCollectionConverter
  • KeyValueConfigurationCollection - Used to configure key/value pairs in your configuration sections
  • NameValueConfigurationCollection - Used to configure name/value pairs in your configuration sections

In addition to all of the classes described above, you will also find other support types used by ProtectedConfigurationSection. All of the old .NET 1.x configuration classes will also still be available in the System.Configuration namespace, but for the most part they can be ignored.