2009/04/28

Javascript debugging in Visual Studio 2005

How to debug (set a breakpoint) javascript in Visual Studio 2005 without installing 3rd party tools/softwares?

First, make sure you uncheck the following settings.

Second, put the keyword "debugger" in your javascript code like this:
function Set()
{
debugger; //this is just like a breakpoint
var control = document.getElementById('Button1');
//......
}
After doing this, you will have full ability just like you are debugging normal C# code. You can use the "Immediate Window" as well, this is the most excited part!

2009/04/25

SQL 2005 Paging

You can find many ways to implement the paging in the stored procedures. Here is the one that I learned from my colleague.
Create PROCEDURE [dbo].[getMemberInfo] (
@pageNumber int = 1, --which page you want to fetch
@rowsPerPage int = 50 --how many rows per page
)
AS
BEGIN
SET NOCOUNT ON;

Declare @startRowIndex int,
@endRowIndex int

Set @startRowIndex = ((@pageNumber - 1) * @rowsPerPage) + 1
Set @endRowIndex = @startRowIndex + @rowsPerPage - 1

Select * 
From (
Select *,
row_number() Over (Order By accountName) As rownum
From dbo.Member
)
Where rownum Between @startRowIndex And @endRowIndex
End
GO

2009/04/17

How to prevent users from keying in numbers

I saw a pretty neat javascript to prevent (or only allow) users from keying numbers. This works for both IE and Firefox. Here is the scripts:
function onKeyPressBlockNumbers(e)
{
//e.keyCode is for IE; e.which is for Firefox
var key = window.event ? e.keyCode : e.which;
var keychar = String.fromCharCode(key);
reg = /\d/;
return !reg.test(keychar);
}
This one is the oppsite purpose:
function onKeyPressOnlyNumbers(e)
{
var key = window.event ? e.keyCode : e.which;
var keychar = String.fromCharCode(key);
reg = /\d/;
return reg.test(keychar);
}
Here is how to use:
<asp:TextBox ID="TextBox1" onkeypress="return onKeyPressBlockNumbers(event);" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBox2" onkeypress="return onKeyPressOnlyNumbers(event);" runat="server"></asp:TextBox>

Note: This cannot prevent users from pasting numbers onto the TextBox.

2009/04/13

AES File Encryption/Decryption

public string AESforFile(string inputFilename, string outputFilename, string key, string IV, bool toEncrypt)
{
  try
  {
    using (FileStream fsInput = new FileStream(inputFilename, FileMode.Open, FileAccess.Read))
    {
      using (FileStream fsOutput = new FileStream(outputFilename, FileMode.Create, FileAccess.Write))
      {
        RijndaelManaged oAES = new RijndaelManaged();
        Rfc2898DeriveBytes oRfc2898DeriveBytes = new Rfc2898DeriveBytes(key + strSalt, Encoding.UTF8.GetBytes(IV));

        oAES.Padding = PaddingMode.PKCS7;
        oAES.Mode = CipherMode.CBC;
        oAES.KeySize = 256;
        oAES.Key = oRfc2898DeriveBytes.GetBytes(32);
        oAES.BlockSize = 128;
        oAES.IV = oRfc2898DeriveBytes.GetBytes(16);

        // Now create a crypto stream through which we are going
        // to be pumping data.
        // The fsOutput is going to be receiving the encrypted bytes.
        CryptoStream oCryptoStream = toEncrypt ?
          oCryptoStream = new CryptoStream(fsOutput, oAES.CreateEncryptor(), CryptoStreamMode.Write) :
          oCryptoStream = new CryptoStream(fsOutput, oAES.CreateDecryptor(), CryptoStreamMode.Write);

        // Now will will initialize a buffer and will be processing the input file in chunks.
        // This is done to avoid reading the whole file (which can be huge) into memory.
        int bufferLen = 4096;
        byte[] buffer = new byte[bufferLen];
        int bytesRead;

        do
        {
          // read a chunk of data from the input file
          bytesRead = fsInput.Read(buffer, 0, bufferLen);
          // encrypt it
          oCryptoStream.Write(buffer, 0, bytesRead);
        }
        while (bytesRead != 0);

        oCryptoStream.Close();
        oAES.Clear();
      }
    }
    return "Success";
  }
  catch (CryptographicException cex)
  {
    return cex.Message;
  }
  catch (IOException ioe)
  {
    return ioe.Message;
  }
}

GridView: Dynamically add cells

How to add a cell dynamically (or programmatically)? If you are going to add a cell without any control in it, here is the way:
e.Row.Cells[e.Row.Cells.Add(new TableCell())].Text = "Phone";
If you are going to add a cell with a server control in it (for example, TextBox), you should do like this:
//create a textbox control & set its attributes
TextBox oTB = new TextBox();
oTB.ID = "TextBox1";
oTB.AutoPostBack = true;
oTB.Attributes.Add("onfocus", "this.select();");
//attach the event
oTB.TextChanged += new EventHandler(TextBox_TextChanged);
//hey, the phone number here is just an example
oTB.Text = "1-800-551-1155";
//here is the key point
e.Row.Cells[e.Row.Cells.Add(new TableCell())].Controls.Add(oTB);
oTB = null;

PS: Add those codes to the GridView's RowDataBound event.

AES String Encryption/Decryption

public string AESforString(string rawString, string key, string IV, bool toEncrypt)
{
  try
  {
    RijndaelManaged oAES = new RijndaelManaged();
    Rfc2898DeriveBytes oRfc2898DeriveBytes = new Rfc2898DeriveBytes(key, Encoding.UTF8.GetBytes(IV));

    oAES.Padding = PaddingMode.PKCS7;
    oAES.Mode = CipherMode.CBC;
    oAES.KeySize = 256;
    oAES.Key = oRfc2898DeriveBytes.GetBytes(32);
    oAES.BlockSize = 128;
    oAES.IV = oRfc2898DeriveBytes.GetBytes(16);

    byte[] rawData;
    byte[] result;
    if (toEncrypt)
    {
      rawData = Encoding.UTF8.GetBytes(rawString);
      result = oAES.CreateEncryptor().TransformFinalBlock(rawData, 0, rawData.Length);
      oAES.Clear();
      return Convert.ToBase64String(result);
    }
    else
    {
      rawData = Convert.FromBase64String(rawString);
      result = oAES.CreateDecryptor().TransformFinalBlock(rawData, 0, rawData.Length);
      oAES.Clear();
      return Encoding.UTF8.GetString(result);
    }
  }
  catch (CryptographicException cex)
  {
    return cex.Message;
  }
}

2009/04/08

The "Save As" function on the web form

Here is how I implement the "Save As" function: (let users download files from server)
private void SaveAs(string contents, string fileName)
{
  try
  {
    //setup the HTTP Header and push the contents to clients
    Response.ClearHeaders();
    Response.Clear();
    Response.Expires = 0;
    Response.Buffer = true;
    Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
    Response.AddHeader("Content-Length", contents.Length.ToString());
    Response.ContentType = "application/octet-stream";
    Response.Write(contents);
    Response.End();
  }
  catch (Exception ex)
  {
    //your error handling here
  }
}

How to call this method? This is one of the ways:
FileInfo oTargetFile = new FileInfo(Server.MapPath("Errorlog.xml"));
if (oTargetFile.Exists)
{
  using (StreamReader oStreamReader = new StreamReader(Server.MapPath("Errorlog.xml")))
  {
    SaveAs(oStreamReader.ReadToEnd(), "Errorlog.xml");
  }
}
oTargetFile = null;

2009/04/07

Calling DOS command with parameters

I saw someone was asking about how to call DOS commands and how to pass the parameters. Here is the way to do it:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "ipconfig.exe";
p.StartInfo.Arguments = @"/all";
p.Start();
p.WaitForExit();
string strResult = p.StandardOutput.ReadToEnd();

PS: If your command doesn't work when you change the parameters, try to comment out the
p.WaitForExit();

Writing texts to a file.

Here are what I use to write texts to a file. First way:
using (StreamWriter oStreamWriter = new StreamWriter(outputFilename))
{
  oStreamWriter.WriteLine(YourTextHere);
  ......
}
Second way:
using (FileStream oFileStream = new FileStream("Errorlog.txt", FileMode.Append))
{
  using (TextWriter oTextWriter = new StreamWriter(oFileStream))
  {
    oTextWriter.WriteLine("DateTime: " + DateTime.Now.ToString());
    oTextWriter.WriteLine("Message: " + ex.Message);
    oTextWriter.WriteLine("Source: " + ex.Source);
  }
}
How to choose the correct FileMode? Take a look of this graph:
This graphic is scaned from the book C# 3.0 in a Nutshell, 3rd Edition. This is a very good C# book, and I will say "Go and grab one".

2009/04/04

Tips: Clean Session/Cache (4/21/2009 updated)

Clean Session:
Session.Clear();
Totally remove the Session:
Session.Abandon();
Clean Cache:
HttpRuntime.Close();
Note: Be careful when using this way to clear the cache (See here). I found a better way to do the same thing from here.
List cacheKeys = new List();
IDictionaryEnumerator cacheEnum = Cache.GetEnumerator();
while (cacheEnum.MoveNext())
{
cacheKeys.Add(cacheEnum.Key.ToString());
}
foreach (string cacheKey in cacheKeys)
{
Cache.Remove(cacheKey);
}

Reference: What is the best way to end session?

2009/04/03

RSA String Encryption/Decryption

Same with the TripleDES, here is what I use to encrypt/decrypt string (not a good idea to encrypt files). Here is the encryption:
public byte[] RSAEncryptString(string data, string xmlKeyString)
{
  try
  {
    RSACryptoServiceProvider oRSA = new RSACryptoServiceProvider();
    oRSA.FromXmlString(xmlKeyString);
    return oRSA.Encrypt(Encoding.UTF8.GetBytes(data), false);
  }
  catch (CryptographicException cex)
  {
    throw cex;
  }
}
Here is the decryption:
public string RSADecryptString(byte[] data, string xmlKeyString)
{
  try
  {
    RSACryptoServiceProvider oRSA = new RSACryptoServiceProvider();
    oRSA.FromXmlString(xmlKeyString);
    return Encoding.UTF8.GetString(oRSA.Decrypt(data, false));
  }
  catch (CryptographicException cex)
  {
    throw cex;
  }
}
It's better to use RSA to generate the public/private key pair:
public List<string> RSAKeypairGenerator()
{
  List<string> lstResult = new List<string>();
  RSACryptoServiceProvider oRSA = new RSACryptoServiceProvider();
  //public key
  lstResult.Add(oRSA.ToXmlString(false));
  //private key
  lstResult.Add(oRSA.ToXmlString(true));
  oRSA.Clear();
  return lstResult;
}

2009/04/01

TripleDES File Encryption/Decryption (6/13/2011 updated)

Here is how I encrypt/decrypt file by using the TripleDES. The inputFilename (and outputFilename) better includes the full path, ex. "C:\Temp\123.pdf".
public string TripleDESforFile(string inputFilename, string outputFilename, string key, string IV, bool toEncrypt)
{
  try
  {
    using (FileStream fsInput = new FileStream(inputFilename, FileMode.Open, FileAccess.Read))
    {
      using (FileStream fsOutput = new FileStream(outputFilename, FileMode.Create, FileAccess.Write))
      {
        PasswordDeriveBytes oPasswordDeriveBytes = new PasswordDeriveBytes(key, Encoding.UTF8.GetBytes(FormatStringLength(IV, 8, '9')));
        TripleDESCryptoServiceProvider oTDES = new TripleDESCryptoServiceProvider();
        oTDES.Mode = CipherMode.CBC;
        oTDES.Padding = PaddingMode.PKCS7;
        //Create the key and set it to the Key property of the TripleDESCryptoServiceProvider object.
        oTDES.Key = oPasswordDeriveBytes.GetBytes(24);  //must 24 bytes
        oTDES.IV = oPasswordDeriveBytes.GetBytes(8);  //must 8 bytes

        // Now create a crypto stream through which we are going
        // to be pumping data.
        // The fsOutput is going to be receiving the encrypted bytes.
        CryptoStream oCryptoStream = toEncrypt ?
          oCryptoStream = new CryptoStream(fsOutput, oTDES.CreateEncryptor(), CryptoStreamMode.Write) :
          oCryptoStream = new CryptoStream(fsOutput, oTDES.CreateDecryptor(), CryptoStreamMode.Write);

        // Now will will initialize a buffer and will be processing the input file in chunks.
        // This is done to avoid reading the whole file (which can be huge) into memory.
        int bufferLen = 4096;
        byte[] buffer = new byte[bufferLen];
        int bytesRead;

        do
        {
          // read a chunk of data from the input file
          bytesRead = fsInput.Read(buffer, 0, bufferLen);
          // encrypt it
          oCryptoStream.Write(buffer, 0, bytesRead);
        }
        while (bytesRead != 0);

        oCryptoStream.Close();
        oTDES.Clear();
      }
    }
    return "Success";
  }
  catch (CryptographicException cex)
  {
    return cex.Message;
  }
  catch (IOException ioe)
  {
    return ioe.Message;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
}

6/13/2011 updated:
Use the PasswordDeriveBytes class to generate the Key and IV for the 3DES.

TripleDES String Encryption/Decryption (6/12/2011 updated)

Here is how I encrypt/decrypt string by using the TripleDES.
public string TripleDESforString(string rawString, string key, string IV, bool toEncrypt)
{
  try
  {
    //Create a PasswordDeriveBytes object and then create a TripleDES key from the password and salt.
    PasswordDeriveBytes oPasswordDeriveBytes = new PasswordDeriveBytes(key, Encoding.UTF8.GetBytes(FormatStringLength(IV, 8, '9')));
    TripleDESCryptoServiceProvider oTDES = new TripleDESCryptoServiceProvider();
    oTDES.Padding = PaddingMode.PKCS7;
    oTDES.Mode = CipherMode.CBC;
    //Create the key and set it to the Key property of the TripleDESCryptoServiceProvider object.
    //oTDES.Key = oPasswordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192, oPasswordDeriveBytes.Salt);
    oTDES.Key = oPasswordDeriveBytes.GetBytes(24);
    oTDES.IV = oPasswordDeriveBytes.GetBytes(8);

    byte[] data;
    byte[] result;
    if (toEncrypt)
    {
      data = Encoding.UTF8.GetBytes(rawString);
      result = oTDES.CreateEncryptor().TransformFinalBlock(data, 0, data.Length);
      oTDES.Clear();
      return Convert.ToBase64String(result);
    }
    else
    {
      data = Convert.FromBase64String(rawString);
      result = oTDES.CreateDecryptor().TransformFinalBlock(data, 0, data.Length);
      oTDES.Clear();
      return Encoding.UTF8.GetString(result);
    }
  }
  catch (CryptographicException cex)
  {
    return cex.Message;
  }
}
The TripleDES class will throw an Exception if you assign it with the weak key. The easy way to prevent this situation is to use the key that generated by the TripleDES itself.
public List<byte[]> TripleDESKeyGenerator()
{
  List<byte[]> lstResult = new List<byte[]>();
  TripleDES oTDES = TripleDESCryptoServiceProvider.Create();
  oTDES.GenerateKey();
  oTDES.GenerateIV();
  lstResult.Add(oTDES.Key);
  lstResult.Add(oTDES.IV);
  oTDES.Clear();
  return lstResult;
}


2/5/2010 updated:
Put on the FormatStringLength() method.
public static string FormatStringLength(string input, int requiredLength, char padding)
{
  if (input.Length < requiredLength)
    input = input.PadRight(requiredLength, padding);
  else if (input.Length > requiredLength)
    input = input.Substring(0, requiredLength);

  return input;
}

6/12/2011 updated:
Replaced the following line
oTDES.Key = oPasswordDeriveBytes.CryptDeriveKey("TripleDES", "SHA1", 192, oPasswordDeriveBytes.Salt);
with
oTDES.Key = oPasswordDeriveBytes.GetBytes(24);

Remove DBNull

If you are getting data from SQL server, it always has a chance that you will get the Null in your table cell. But the meaning of "Null" in database is different than it in the .Net. So how to remove the Null from the resultset getting from the database?
1.Use IsNull() function in your stored procedures.
Select Name, IsNull(Age, 18) From Members
2.Use the following simple method
public DataTable RemoveDBNull(DataTable dt)
{
  for (int i = 0; i < dt.Rows.Count; i++)
  {
    for (int j = 0; j < dt.Columns.Count; j++)
    {
      if (dt.Rows[i][j] == DBNull.Value)
        dt.Rows[i][j] = 0;
    }
  }
  return dt;
}