Search Here

Custom Search

Wednesday, August 20, 2008

Common Validation and Length Validation with Regular Expression in ASP.NET


Download the complete source code.

Introduction

Input validation is very common and important in any kind of application. In case of web application server side validation is a must and client side validation is highly anticipated. As you know ASP.NET provides you some handfull validation controls like RequiredFiledValidator, RegularExpressionValidator etc. Most of the time we have to check whether user has given the correct number, date, time or anything as input. To validate such things we use RegularExpressionValidator.

In this article I'll provide an Util class full of some regular expressions for common input validation. The main attractive part is length validation of textarea control of html. As you know in case of textfield you can tell the max length of it. But for textarea you cannot do it. So normally we have to write some javascript function to check the length before form submit.

But in ASP.NET when you use TextBox, setting the TextMode property as MultiLine the MaxLength property does not work. So if you want to put restriction to limit the input length of the TextBox you have to find an alternate way.

Yes, here I'll show how you can do this by simply writing a Regular Expression.

The code

The RegExp class



using System;
using System.Collections.Generic;
using System.Text;

namespace Util
{
public class RegExp
{
public static readonly string Url = "[a-zA-Z0-9-_\\$]+(//.[a-za-z0-9-_//$]+)?\\??" +
"[a-zA-Z0-9-_\\$]+=?[a-zA-Z0-9-_\\$]+(&[a-zA-Z0-9-_\\$]+=" +
"[a-zA-Z0-9-_\\$]+)*";">\\.[a-zA-Z0-9-_\\$]+)?\\??" +
"[a-zA-Z0-9-_\\$]+=?[a-zA-Z0-9-_\\$]+(&" +
"[a-zA-Z0-9-_\\$]+=[a-zA-Z0-9-_\\$]+)*";

public static readonly string Date = "(0[1-9]|[12][0-9]|3[01])[-]" +
"(0[1-9]|1[012])[-]((175[7-9])|(17[6-9][0-9])|(1[8-9][0-9][0-9])|" +
"([2-9][0-9][0-9][0-9]))";
// supports dates from 1-1-1757 to 31-12-9999 for SQL Server 2000 Date Range

public static readonly string Time = "(0[1-9]|[1][0-2])[:]" +
"(0[0-9]|[1-5][0-9])[:](0[0-9]|[1-5][0-9])[ ][A|a|P|p][M|m]";
public static readonly string Number = "[-+]?[0-9]*\\.?[0-9]*";
public static readonly string Digit = "[0-9]*";
public static readonly string NonNegative = "[+]?[0-9]*\\.?[0-9]*";

public static string MaxLength(int len)
{
return "[\\s\\S]{0," + len.ToString() + "}";
}
}
}

The ValidationMessages class



using System;
using System.Collections.Generic;
using System.Text;

namespace Resource
{
public class ValidationMessages
{

public static readonly string Url = "* Please enter a valid URL.<br>Valid " +
"characters are all alphanumeric characters and .?" +
"&_=-$<br> example: home.aspx?id=5&name=$my_name";
public static readonly string Required = "* Required";
public static readonly string Date = "* Please enter a valid date in dd-MM-yyyy format.";
public static readonly string Time = "* Please enter a valid time in hh:mm:ss am format.";
public static readonly string Number = "* Must be a valid number.";
public static readonly string Digit = "* Must be a valid whole number.";
public static readonly string NonNegative = "* Must be a non-negative number.";

public static string MaxLength(int len)
{
return "* Maximum " + len.ToString() + " characters are allowed.";
}
}
}

Using the Code

The usage is very simple. See the example page.

Defaul.aspx page.



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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3>
Validation Example</h3>
<table border="1" width="50%">
<tr>
<td style="width: 200px">
<asp:Label ID="CommentLabel"
runat="server" Text="Comment:">
</asp:Label></td>
<td>
<asp:TextBox ID="CommentTextBox" runat="server"
TextMode="MultiLine" Width="500px" />
<asp:RegularExpressionValidator ID="CommentValidator"
runat="server" ControlToValidate="CommentTextBox">
</asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<asp:Label ID="DateLabel" runat="server"
Text="Date:"></asp:Label></td>
<td>
<asp:TextBox ID="DateTextBox"
runat="server" Width="500px" />
<asp:RegularExpressionValidator ID="DateValidator" runat="server"
ControlToValidate="DateTextBox"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<asp:Label ID="TimeLabel" runat="server"
Text="Time:"></asp:Label></td>
<td>
<asp:TextBox ID="TimeTextBox" runat="server" Width="500px" />
<asp:RegularExpressionValidator ID="TimeValidator" runat="server"
ControlToValidate="TimeTextBox"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<asp:Label ID="NumberLabel" runat="server"
Text="Number:"></asp:Label></td>
<td>
<asp:TextBox ID="NumberTextBox" runat="server" Width="500px" />
<asp:RegularExpressionValidator ID="NumberValidator" runat="server"
ControlToValidate="NumberTextBox"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<asp:Label ID="DigitLabel" runat="server"
Text="Digit:"></asp:Label></td>
<td>
<asp:TextBox ID="DigitTextBox" runat="server" Width="500px" />
<asp:RegularExpressionValidator ID="DigitValidator" runat="server"
ControlToValidate="DigitTextBox"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<asp:Label ID="NonNegativeLabel" runat="server"
Text="Non Negative:"></asp:Label></td>
<td>
<asp:TextBox ID="NonNegativeTextBox" runat="server" Width="500px" />
<asp:RegularExpressionValidator ID="NonNegativeValidator" runat="server"
ControlToValidate="NonNegativeTextBox"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td>
<asp:Label ID="UrlLabel" runat="server" Text="Url:">
</asp:Label></td>
<td>
<asp:TextBox ID="UrlTextBox" runat="server" Width="500px" />
<asp:RegularExpressionValidator ID="UrlValidator" runat="server"
ControlToValidate="UrlTextBox"></asp:RegularExpressionValidator>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>

Defaul.aspx.cs page



using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Util;
using Resource;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CommentValidator.ValidationExpression = RegExp.MaxLength(50);
CommentValidator.ErrorMessage = ValidationMessages.MaxLength(50);

DateValidator.ValidationExpression = RegExp.Date;
DateValidator.ErrorMessage = ValidationMessages.Date;

TimeValidator.ValidationExpression = RegExp.Time;
TimeValidator.ErrorMessage = ValidationMessages.Time;

NumberValidator.ValidationExpression = RegExp.Number;
NumberValidator.ErrorMessage = ValidationMessages.Number;

DigitValidator.ValidationExpression = RegExp.Digit;
DigitValidator.ErrorMessage = ValidationMessages.Digit;

NonNegativeValidator.ValidationExpression = RegExp.NonNegative;
NonNegativeValidator.ErrorMessage = ValidationMessages.NonNegative;

UrlValidator.ValidationExpression = RegExp.Url;
UrlValidator.ErrorMessage = ValidationMessages.Url;
}
}

Screenshot

screenshot.jpg

Here the Url validator expression and message was need of my business requirement. If you have a different requirement then customize yours one.

Download the complete source code.

Tuesday, August 19, 2008

Generating Unique Key(Finger Print) for a Computer for Licensing Purpose


Download the complete source code.


Introduction

For licensing purpose according to me the best way and secure way is to generate an unique key for client's machine and providing a corresponding license key for that key. For this purpose you can take help of the unique id of client's computer's motherboard, BIOS and processor's. When you get these IDs you can generate any key of your preferable format.

Year ago I found a very handy and useful code in C# by searching net to get these IDs. And its serving me perfectly so far. Thanks to the original author of the code.

I added some additional code to generate a 128 bit key of a machine. The output is a nice looking key in hexadecimal format (eg. 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9)

Suggestions

I have few suggestions on this regard.

*) Generate key from only Motherboard, Processor and BIOS. Since user normally doesn't chagne these parts.

*) Don't use MAC ID, Graphics Card ID AND Disk ID. Since its very common to change these devices.

*) It takes significant time to get IDs of devices. So make the finger print generating fucntion static and save it in a static variable so that it generates the key only for one time in the whole application.

The Code

Here is the class. The code in the region "Original Device ID Getting Code" is from the original author.



using System;
using System.Management;
using System.Security.Cryptography;
using System.Security;
using System.Collections;
using System.Text;
namespace Security
{
/// <summary>
/// Generates a 16 byte Unique Identification code of a computer
/// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
/// </summary>
public class FingerPrint
{
private static string fingerPrint = string.Empty;
public static string Value()
{
if (string.IsNullOrEmpty(fingerPrint))
{
fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId()
//+"\nDISK >> "+ diskId() + "\nVIDEO >> " + videoId() +"\nMAC >> "+ macId()
);
}
return fingerPrint;
}
private static string GetHash(string s)
{
MD5 sec = new MD5CryptoServiceProvider();
ASCIIEncoding enc = new ASCIIEncoding();
byte[] bt = enc.GetBytes(s);
return GetHexString(sec.ComputeHash(bt));
}
private static string GetHexString(byte[] bt)
{
string s = string.Empty;
for (int i = 0; i < bt.Length; i++)
{
byte b = bt[i];
int n, n1, n2;
n = (int)b;
n1 = n & 15;
n2 = (n >> 4) & 15;
if (n2 > 9)
s += ((char)(n2 - 10 + (int)'A')).ToString();
else
s += n2.ToString();
if (n1 > 9)
s += ((char)(n1 - 10 + (int)'A')).ToString();
else
s += n1.ToString();
if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
}
return s;
}
#region Original Device ID Getting Code
//Return a hardware identifier
private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
{
string result = "";
System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
if (mo[wmiMustBeTrue].ToString() == "True")
{
//Only get the first one
if (result == "")
{
try
{
result = mo[wmiProperty].ToString();
break;
}
catch
{
}
}
}
}
return result;
}
//Return a hardware identifier
private static string identifier(string wmiClass, string wmiProperty)
{
string result = "";
System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
System.Management.ManagementObjectCollection moc = mc.GetInstances();
foreach (System.Management.ManagementObject mo in moc)
{
//Only get the first one
if (result == "")
{
try
{
result = mo[wmiProperty].ToString();
break;
}
catch
{
}
}
}
return result;
}
private static string cpuId()
{
//Uses first CPU identifier available in order of preference
//Don't get all identifiers, as very time consuming
string retVal = identifier("Win32_Processor", "UniqueId");
if (retVal == "") //If no UniqueID, use ProcessorID
{
retVal = identifier("Win32_Processor", "ProcessorId");
if (retVal == "") //If no ProcessorId, use Name
{
retVal = identifier("Win32_Processor", "Name");
if (retVal == "") //If no Name, use Manufacturer
{
retVal = identifier("Win32_Processor", "Manufacturer");
}
//Add clock speed for extra security
retVal += identifier("Win32_Processor", "MaxClockSpeed");
}
}
return retVal;
}
//BIOS Identifier
private static string biosId()
{
return identifier("Win32_BIOS", "Manufacturer")
+ identifier("Win32_BIOS", "SMBIOSBIOSVersion")
+ identifier("Win32_BIOS", "IdentificationCode")
+ identifier("Win32_BIOS", "SerialNumber")
+ identifier("Win32_BIOS", "ReleaseDate")
+ identifier("Win32_BIOS", "Version");
}
//Main physical hard drive ID
private static string diskId()
{
return identifier("Win32_DiskDrive", "Model")
+ identifier("Win32_DiskDrive", "Manufacturer")
+ identifier("Win32_DiskDrive", "Signature")
+ identifier("Win32_DiskDrive", "TotalHeads");
}
//Motherboard ID
private static string baseId()
{
return identifier("Win32_BaseBoard", "Model")
+ identifier("Win32_BaseBoard", "Manufacturer")
+ identifier("Win32_BaseBoard", "Name")
+ identifier("Win32_BaseBoard", "SerialNumber");
}
//Primary video controller ID
private static string videoId()
{
return identifier("Win32_VideoController", "DriverVersion")
+ identifier("Win32_VideoController", "Name");
}
//First enabled network card ID
private static string macId()
{
return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
}
#endregion
}
}

Upcoming Code

Later I'll show how I generated the license key from the unique machine key. The license key contains many information like the Product Name, License Start Date, End Date and the Key.


Download the complete source code.

IntelliJ IDEA 8 Released!

Hurray! At last IntelliJ IDEA 8.0 has been released. I was waiting for a long time for it. For J2EE developers there are some new fruits. I was specially waiting for the FreeMarker(FTL) plugin. In IDEA 8.0 it has been incorporated.

Here is the link and the original post:

http://blogs.jetbrains.com/idea/2008/08/intellij-idea-8-milestone-1-is-here/

It is really a lucky concourse of circumstances that today, 8/8/08, we’re releasing IntelliJ IDEA 8 Milestone 1!

This release is a preview of IntelliJ IDEA 8, which is due out by the end of Fall 2008.
Milestone 1 demonstrates greatly extended support for modern technologies, frameworks and languages, plus noticeably better IDE performance.
Here’s the list of major new features that are already available to try out:

  • JBoss Seam Integration
  • Javascript/Flex Debugger
  • Greatly improved performance
  • Spring 2.5
  • FreeMarker, Velocity, GWT 1.5
  • REST WebServices support
  • Struts 2
  • Multi-dialect SQL Console
  • New Java refactorings
  • Even smarter code completion
  • Numerous new code inspections
  • and many more

Read more about all the new features, watch them in live action, and get your copy of the fresh release to try it all for yourself.

Tuesday, August 12, 2008

How to easily use jQuery DatePicker in ASP.NET



Download the complete source code.


Introduction

JQuery is an excellent javascript library to build modern user interactive website.
Its very easy to use jQuery in any web application. jQuery has a strong set of javascript UI like datePicker, Tab Panel etc.

I've written a small Utility class to use jQuery datePicker in ASP.NET and publishing it in this post.
Its very simple to use this class. You just need to pass the Page object and TextBox of your page.

Screen Shot

ScreenShot.jpg

Using the code


See the class:



using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Util
{
public class JQueryUtils
{
public static void RegisterTextBoxForDatePicker(Page page, params TextBox[] textBoxes)
{
RegisterTextBoxForDatePicker(page, "dd-mm-yy", textBoxes);
}
public static void RegisterTextBoxForDatePicker(Page page, string format, params TextBox[] textBoxes)
{
bool allTextBoxNull = true;
foreach (TextBox textBox in textBoxes)
{
if (textBox != null) allTextBoxNull = false;
}
if (allTextBoxNull) return;
page.ClientScript.RegisterClientScriptInclude(page.GetType(), "jquery", "JQuery/jquery.js");
page.ClientScript.RegisterClientScriptInclude(page.GetType(), "jquery.ui.all", "JQuery/ui/jquery.ui.all.js");
page.ClientScript.RegisterClientScriptBlock(page.GetType(), "datepickerCss", "<link rel=\"stylesheet\" href=\"JQuery/themes/flora/flora.datepicker.css\" />");
StringBuilder sb = new StringBuilder();
sb.Append("$(document).ready(function() {");
foreach (TextBox textBox in textBoxes)
{
if (textBox != null)
{
sb.Append("$('#" + textBox.ClientID + "').datepicker({dateFormat: \"" + format + "\"});");
}
}
sb.Append("});");
page.ClientScript.RegisterClientScriptBlock(page.GetType(), "jQueryScript", sb.ToString(), true);
}
}
}


The usage is very simple. If you have a TextBox named MyDateTextBox in your .aspx page then you have to write following line in the Page_Load event to attach the TextBox with jQuery.



protected void Page_Load(object sender, EventArgs e)
{
Util.JQueryUtils.RegisterTextBoxForDatePicker(Page, MyDateTextBox);
}


The second parameter takes variable arguments. So you can pass any number of TextBox to the function. There is also an overloaded function to take your desired date format.

You must download the jQuery library from jQuery UI site http://ui.jquery.com/download

You can only download the files for datePicker. But remember to rename the .js files in My JQueryUtils class. You can see I've written the jQuery core library js file name, .ui.all.js file and the .css file for datePicker.

Download the complete source code.