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.

Saturday, June 7, 2008

Properly display paragraphs in browser

When we write something in several paragraphs in textarea of browser then it shows as it is in teaxtarea. But when we want to show the text in read only mode then the paragraphs loose their identity. I mean you can not separate the paragraphs from each other. So we need to replace the newlines of the text by
.

I have written a simple function named ‘keepWhiteSpace’ to do this conversion and I used it in many of Therap's forms to display the saved text as it is. Usage is very simple.

For example, if you want to show your text in a cell then write as follows:

${therap.keepWhiteSpace(myText)}

The implementation is very simple.

<#function keepWhiteSpace value>
<#return value?replace("\r\n","<br>")?replace("\n\r","<br>")?replace("\r","<br>")?replace("\n","<br>")>
</#function>

Ftl(Free Marker Tag Library) users can use it without rewriting any new one. JSP users need to write a tag using the logic.

Note that I haven’t replaced spaces by

Thursday, June 5, 2008

The word ‘Mother’ in different languages

Definitely the first word a child learns after birth is the word ‘Mother’ in his own language. Its also the most favorite word of every human being. Surprisingly almost in every language mother is initialed by the letter ‘m’. Or at least contains ‘m’ in the word. This is really amazing. What may be the cause? May be its easy to produce sounds from lips for a child. Or they start creating sound like ‘mmmm….’ and ultimately they learn the word mother.

Here is a big list of translation.

http://www.mothersdaycelebration.com/mother-in-different-languages.html

Monday, May 26, 2008

Insertion problem with ASP.NET AccessDataSource

If you try to use ASP.NET AccessDataSource then you may face a problem while inserting rows to database through the dataSource. It happens when you have an auto increment identity column. When you drag & drop an AccessDataSource Visual Studio.NET generates the SELECT, INSERT, DELETE, UPDATE Command for you as your chosen option. But you will get exception message when you try to save a new row. The cause is the generated insert query is wrong. Actually VS.NET don't consider the identity column and try to insert value in the column.

The work around is just remove the ID column from the insert command and remove a parameter('?') from the query parameter list. Also remove the ID column info from the insert command parameter collection.

Then you will find its working fine.

Testing Terminology

I think every developer should be familiar with some software testing terminologies, especially different methods of testing. You may have heard about White Box Testing, Black Box Testing, Unit Testing, Regression Testing, Integration Testing etc. If you don’t want to spend much time after this but feeling interest to know about then visit the following link. Its a very simple and short article.

http://testingsolution.blogspot.com/2006/12/what-is-use-of-different-kind-of.html

If you wanna dig more then search google.

Thursday, May 15, 2008

Mounting NTFS partition in Debian

Currently Debian doesn’t support mounting NTFS partition in read/write mode. You can only mount in read only mode.

To mount in read/write mode you have to install third party package/driver. NTFS-3G is the favorite one.

Here is the detail info.

http://www.ntfs-3g.org/index.html

Thursday, February 7, 2008

How to show a pdf in landscape mode using iText API in Java

This post may help the pdf developers who use iText. I mean who use the com.lowagie.text and its sister packages.

I guess you (iText users) are familiar with the class
com.lowagie.text.Document

We have to tell this class the page size of the pdf in the following way.

document.setPageSize(PageSize.A4));   // suppose document is the instance of Document

But you will not find the word ‘Landscape’ anywhere in the context. So, how can you tell it to generate a pdf of landscape page size? Yes there is a simple but uncommon way to specify this.
See the solution below:

document.setPageSize(PageSize.A4.rotate());

Actually PageSize.A4 is a static variable of type com.lowagie.text.Rectangle

So by rotating it you are getting the landscape size of A4 page.

Wednesday, January 16, 2008

A simple method to compare versions

Sometimes we may need to compare two versions to know which one is newer and which one is older or whether both of those are same versions. Let me explain. Suppose you have two versions in hand as String “7.2.1″ and “7.1.1″. Now you wanna know which one is the later version. At the very first sight you may think that simple string comparison will give the correct decision. But unfortunately it won’t work correctly always. Think about this input : “10.0.1″ and “9.5.2″. String comparison will return the second one as latest version. But you expect the first one. So definitely we should change the algorithm.

A very simple algorithm is to split the input string by “.” and compare individual components. It guarantees you the correct output. Here is my implementation of the method. I have applied Unit Testing (www.junit.org , www.nunit.org) on it and it passes all possible test cases. You can use it without any doubt and it works for any length of versions.

Here is the implementation. Same code will run both in Java and C#.NET



/* This method compares two given versions and returns 0,1 or -1
It returns 0 if both versions are equal,
1 if first version is newer than second one,
-1 if first version is older than the second one.
Example:
compareVersion("7.1","7.1") will return 0
compareVersion("7.1.1","7.1.1") will return 0
compareVersion("7.1","7.1.1") will return -1
compareVersion("7.1","7.2") will return -1
compareVersion("7.1","7.2.2") will return -1
compareVersion("7.2","7.1") will return 1
compareVersion("7.2.0","7.1") will return 1
compareVersion("7.2.0","7.2") will return 0
compareVersion("7.abc.0","7.2") will throw exception
*/
public static int compareVersion(String v1, String v2) throws Exception {
String[] v1Tokens = v1.split("\\."); // for C#: String[] v1Tokens = v1.split(".");
String[] v2Tokens = v2.split("\\."); // for C#: String[] v2Tokens = v2.split(".");
int maxLen;

if (v1Tokens.length > v2Tokens.length)
maxLen = v1Tokens.length;
else
maxLen = v2Tokens.length;

for (int i = 0; i < maxLen; i++) {
int n1, n2;

n1 = n2 = 0;

try {
if (i < v1Tokens.length)
n1 = Integer.parseInt(v1Tokens[i]);

if (n1 < 0)
throw new Exception(v1 + " is not a valid version.");
} catch (Exception ex) {
throw new Exception(v1 + " is not a valid version.");
}

try {
if (i < v2Tokens.length)
n2 = Integer.parseInt(v2Tokens[i]);

if (n2 < 0)
throw new Exception(v2 + " is not a valid version.");
} catch (Exception ex) {
throw new Exception(v2 + " is not a valid version.");
}

if (n1 > n2)
return 1;
else if (n1 < n2)
return -1;
}

return 0;
}