2009/12/12

[ASP.Net]Dynamically assign your page's background image

I would like to change/assign a page's background image depends on some conditions, and here is what I did.
1.Assign an id to the body and add the runat="server" to it.

2.Add the following code to your code-behind (you can put it in the Page_Load event)
if (ConfigurationManager.ConnectionStrings["MyWebsite"].ConnectionString.Contains("test"))
body1.Style.Add("background-image", @"url(Images/test.jpg)");
else
body1.Style.Add("background-image", @"url(Images/production.jpg)");
Modify the if statement to meet your needs.

2009/12/02

[C# 2.0] Get and Check Daylight Saving Time (DST)

using System.Globalization;

public static DataTable GenerateDST(int startYear, int endYear)
{
  DataTable dt = new DataTable();
  //get the current timezone
  TimeZone oTimeZone = TimeZone.CurrentTimeZone;
  DaylightTime oDST;

  dt.Columns.Add("Year");
  dt.Columns.Add("Start Date");
  dt.Columns.Add("End Date");

  for (int i = startYear; i <= endYear; i++)
  {
    oDST = oTimeZone.GetDaylightChanges(i);
    dt.Rows.Add(oDST.Start.Year, oDST.Start.ToShortDateString(), oDST.End.ToShortDateString());
  }

  oTimeZone = null;
  oDST = null;

  return dt;
}

2009/11/09

[C#]My simple version of Captcha

This is my own version of Captcha. It's easy and simple. You can improve it with your ideas or needs.

2009/11/06

Allowing only one instance: a simple approach

This is a simple and easy way to do it if your requirement is simple. Otherwise you should use Mutex.
using System.Diagnostics;

private void Form1_Load(object sender, EventArgs e)
{
 try
 {
  string moduleName = Process.GetCurrentProcess().MainModule.ModuleName;
  string processName = Path.GetFileNameWithoutExtension(moduleName);
  Process[] aryProcess = Process.GetProcessesByName(processName);

  if (aryProcess.Length > 1)
  {
   MessageBox.Show("This program is running already!");
   this.Close();
  }

  //...
 }
 catch (Exception ex)
 {
  //...
 }
}
Note: This will check the process based on the filename. It will not work if the filename is different. For example, if you make a copy of your program (let's say FindMP3.exe) and rename it to a different name like FindMP3_1.exe. People can run FindMP3.exe and FindMP3_1.exe at the same time. You can fix this by checking the filename at program startup.

You can find other approaches from here.

2009/10/20

[C#]Simple windows registry manipulation

using Microsoft.Win32;

//Attempt to open the key.
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Play\WindowPosition");

//The key doesn't exist if it returns null.
if (key == null)
{
//Create & open it.
key = Registry.CurrentUser.CreateSubKey(@"Software\Play\WindowPos");
key.SetValue("PositionX", Location.X);
key.SetValue("PositionY", Location.Y);
}
else
{
//Get value
Location.X = key.GetValue("PositionX");
Location.Y = key.GetValue("PositionY");
}

2009/10/19

GetWords

Name: GetWords
Version: 1.3
Platform: Windows with .Net Framework 2.0 installed
Introduction:
Fetch words from the given article. It will fetch, sort, remove duplicated words. It will ignore the word that less than 3 characters like am, is, as... etc.
How to use:
1.Paste anything you want to parse on the left-hand side textbox.
2.Click the "Get Words!" button, and the result will show on the right-hand side.

2009/10/07

KB: You must call the Bind method before performing this operation.

I got this error message: "You must call the Bind method before performing this operation." when using the UDP protocol to communicate with another application. Here is the simplified code
.......
IPAddress serverIP = IPAddress.Parse("xx.xx.xx.xx");
IPEndPoint serverEP = new IPEndPoint(serverIP, 12345);
UdpClient client = new UdpClient();

//start listening
client.BeginReceive(new AsyncCallback(ReceiveCallback), serverEP); //here causes the problem
//send message to server and wait for response
client.Send(Encoding.UTF8.GetBytes("Hello"), "Hello".Length, serverEP);
.....
After spending so many hours on this issue, I finally figure out what the problem is.

[C#][Winform]Show Confirm window

In ASP.Net you can popup a confirm window easily. See this and this. How to do the same thing in windows form? Here is the easiliest way I know:
if (MessageBox.Show("Are you sure you want to delete it?","Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
 //Your code here.
}

2009/09/17

I Am Busy! 1.0

Name: I Am Busy!
Version: 1.0
OS: Windows with .Net Framework 2.0 installed.
Introduction:
Want to take a break with an excuse? :)
How to use:
Just click on the "OK" button once you set the title, showing message, total running time and refresh interval (or run it with the default value). You can take a break then.
The program will close automatically after the given time is reached.

2009/08/27

[Winform] Set ComboBox's value by the given value

Here is the same purpose of the DropDownList control. Here is the same thing for the winform ComboBox control.
internal static void SetDropDownByText(ComboBox cbox, string text)
{
  if (cbox != null)
  {
    DataTable dt = (DataTable)cbox.DataSource;
    for (int i = 0; i < dt.Rows.Count; i++)
    {
      if ((string)dt.Rows[i][cbox.DisplayMember] == text)
      {
        cbox.SelectedIndex = i;
        break;
      }
    }
  }
}

internal static void SetDropDownByValue(ComboBox cbox, string text)
{
  if (cbox != null)
  {
    DataTable dt = (DataTable)cbox.DataSource;
    for (int i = 0; i < dt.Rows.Count; i++)
    {
      if ((string)dt.Rows[i][cbox.ValueMember] == text)
      {
        cbox.SelectedIndex = i;
        break;
      }
    }
  }
}
How to use:
SetDropDownByText(cboxCustomer, "Kenny");
SetDropDownByValue(cboxCustomer, "VIP0001");

There must be a easier way to do the same thing. Let me know if you have one.

2009/07/15

Serialize/Deserialize object to/from binary format

My original goal is to serialize List and List object, but I believe this method can be applied to other data types.
using System.Runtime.Serialization.Formatters.Binary;

public static string SerializeObject(object data)
{
    BinaryFormatter formatter = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream())
    {
        //this is the key: serialize
        formatter.Serialize(ms, data);

        using (TextReader tr = new StreamReader(ms))
        {
            //set the position
            ms.Seek(0, SeekOrigin.Begin);
            return tr.ReadToEnd();
        }
    }
}

public static object DeSerializeObject(string data)
{
    BinaryFormatter formatter = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(data)))
    {
        //set the position
        ms.Seek(0, SeekOrigin.Begin);
        return formatter.Deserialize(ms);
    }
}
Here is how to use:

2009/06/30

Tips: Prevent SSRS report caching

There are many ways to turn off the report cache, but many of them need you to have enough privilege to change the report or server settings. There is one approach that everyone can do without any privilege: comtrol the parameters in the url.

Append this commend to the end of the url:
&rc:emissionTime=633819525738564717
The number should be random, and you can do like this:
"http://.....&rc:emissionTime=" + DateTime.Now.Ticks;

The it's the same trick like this one.

2009/06/11

Download a single file from the remote FTP site (Updated)

Three approaches to download a file from FTP server: WebRequest, FtpWebRequest, and WebClient. Here are the examples:
url = "ftp://xxx.xxx.xxx.xxx/test.txt"

WebRequest
using System.Net;  //don't forget this
public string DownloadFile(string url, string username, string pw)
{
  string strResult = "";
  try
  {
    WebRequest oRequest = HttpWebRequest.Create(new Uri(url));
    oRequest.Credentials = new NetworkCredential(username, pw);
    WebResponse oResponse = oRequest.GetResponse();

    using (StreamReader sr = new StreamReader(oResponse.GetResponseStream()))
    {
      strResult = sr.ReadToEnd();
      sr.Close();
    }

    oRequest = null;
    oResponse = null;
  }
  catch (WebException wex)
  {
    //your error handling here
  }
  return strResult;
}

2009/06/03

ASP.Net: State Management

I strongly recommend this document (from MS) if you would like to truly understand this topic.

2009/05/29

Get browser capabilities

I learn from Ramp Up. This is useful if you want to know client support javascript or not.
HttpBrowserCapabilities browser = Request.Browser;
Label1.Text = "Browser Capabilities\n"
  + "Type = " + browser.Type + "\n"
  + "Name = " + browser.Browser + "\n"
  + "Version = " + browser.Version + "\n"
  + "Major Version = " + browser.MajorVersion + "\n"
  + "Minor Version = " + browser.MinorVersion + "\n"
  + "Platform = " + browser.Platform + "\n"
  + "Is Beta = " + browser.Beta + "\n"
  + "Is Crawler = " + browser.Crawler + "\n"
  + "Is AOL = " + browser.AOL + "\n"
  + "Is Win16 = " + browser.Win16 + "\n"
  + "Is Win32 = " + browser.Win32 + "\n"
  + "Supports Frames = " + browser.Frames + "\n"
  + "Supports Tables = " + browser.Tables + "\n"
  + "Supports Cookies = " + browser.Cookies + "\n"
  + "Supports VBScript = " + browser.VBScript + "\n"
  + "Supports JavaScript = " + browser.EcmaScriptVersion.ToString() + "\n"
  + "Supports Java Applets = " + browser.JavaApplets + "\n"
  + "Supports ActiveX Controls = " + browser.ActiveXControls + "\n";
Please replace the "\n" with "<br />".

2009/05/23

Javascript: Get client's TimeZone

How to know client's time and time zone? The simplest way that can do this is using the javascript.
<script type="text/javascript">
function displayTime()
{
var localTime = new Date();
//this one will give you the GMT offset
var timezone = localTime.getTimezoneOffset()/60 * (-1);
var div = document.getElementById("div1");
div.innerText = "GMT" + timezone;
}
</script>
Or simply use
<script type="text/javascript">
function displayTime()
{
var div = document.getElementById("div1");
div.innerText = (new Date()).toString();
}
</script>

2009/05/14

SQL 2005: T-SQL Get table name or Stored Procedure name

How to get all the tables' name?
Select * 
From sysobjects 
Where type = 'U'
Order By name
Change the type to 'P' and you will get all the Stored Procedures.
Change the type to 'F' and you will get all the UDF (User-Defined Function).
More details from here.

Another way to get the tables:
Select *
From sys.tables
How to get the content of stored procedures?
Select text From syscomments Where id = 
(Select id From sysobjects Where type='P' and name = 'SprocName')
or
Exec sp_helptext SprocName
I prefer the second one.

2009/05/13

MultiThread in ASP.Net

How to use multithread in ASP.Net web form? Here is what I did:
private void MethodA(List<string> data)
{
//runing some stuff

//create a new thread to call another method
ThreadPool.SetMaxThreads(5, 5);
ThreadPool.QueueUserWorkItem(new WaitCallback(MethodB), paramsNeededByMethodB);

//keep running your original logic
//.......
}

private void MethodB(object parameters)
{
//cast to the correct data type
List<string> lstData = (List<string>)parameters;

//start your logic from here
//.......
}
Note:
1. MethodB must take the object as a parameter, no other data type is allowed.
2. Don't use too many threads. IIS will manage threads by itself. Here I set the max thread to 5.

[ASP.Net]Set TextBox to ReadOnly

Set TextBox's ReadOnly property to "True" will cause many side effects. How to retain all the functionalities and also have the ReadOnly function turn on? Here is the better way to do this compare with setting the ReadOnly property directly.
TextBox1.Attributes.Add("readonly", "readonly");
Let me know if you have better approach. :)

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;
}

2009/03/30

The light bar for the GridView control

Add the following codes to your GridView's RowDataBound event:
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
  {
    e.Row.Attributes.Add("onmouseover", "currentcolor = this.style.backgroundColor;this.style.backgroundColor='#6699ff'");
    e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor = currentcolor");
  }
}
Move your mouse over the GridView control and you will see the result.

[C# 2.0] How to load different culture's date time?

How to load other culture's Date and Time format without changing the Region's setting in the Control Panel? Here is what I did:
//change the culture in order to read the DateTime
DateTimeFormatInfo oDateTimeFormatInfo = (new CultureInfo("zh-tw")).DateTimeFormat;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("zh-tw");
Don't forget to include the namespace:

using System.Globalization;
using System.Threading;

Reference

2009/03/28

Detect .Net Framework (1/19/2010 updated)

Sometimes you need to detect clients' environment in order to run your .net winform or webform application. I ever thought about using the System.Environment.Version, but if user doesn't have any .net framework installed on his/her machine, how can he/she run this code to get the .net version? It turns out that we have to use other technologies to detect the .net framework (like search user's registry or system folders ... etc).
Here is what I found on the Microsoft website, and I did some minor changes on it. You can copy the following code and save it as "DetectDotNet.html".
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html >
 <head>
  <title>Test for NET Framework</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <script type="text/javascript" language="JavaScript">
  //you can change the version that you want to detect
  var RequiredFXVersion = "2.0.50727";

  function check()
  {
   var foundVer = CheckRequiredFXVersion(RequiredFXVersion);
   if (foundVer != null)
   {
    result.innerHTML = "This computer has the correct version of the .NET Framework: " + foundVer + "." + "<br/>"
     + "This computer's userAgent string is: " + navigator.userAgent + ".";
   }
   else
   {
    result.innerHTML = "This computer does not have the correct version of the .NET Framework.<br/>"
     + "<a href='http://msdn.microsoft.com/windowsvista/default.aspx'>Click here</a> "
     + "to get .NET Framework 3.0 now.<br>"
     + "This computer's userAgent string is: " + navigator.userAgent + ".";
   }
  }

  //
  // Retrieve available versions from the user agent string
  // and check if any of them match the required version.
  //
  function CheckRequiredFXVersion(requiredVersion)
  {
   var userAgentString = navigator.userAgent.match(/\.NET CLR[ .][0-9.]+/g);
   if (userAgentString != null)
   {
    var i;
    for (i = 0; i < userAgentString.length; ++i)
    {
     var ver = userAgentString[i].slice(9);
     if (CheckVersion(requiredVersion, ver))
      return ver;
    }
   }
   return null;
  }

  //
  // Check if a specific version satisfies the version requirement.
  //
  function CheckVersion(requiredVersion, ver)
  {
   requiredVersion = requiredVersion.split(".");
   ver = ver.split(".");

   // Major versions must match exactly.
   if (requiredVersion[0] != ver[0])
    return false;

   // Minor/build numbers must be at least the required version.
   var i;
   for (i = 1; i < requiredVersion.length && i < ver.length; i++)
   {
    if (new Number(ver[i]) < new Number(requiredVersion[i]))
     return false;
   }
   return true;
  }
  </script>
 </head>
 <body onload="javascript:check();">
  <div id="result" />
 </body>
</html>
So next time you can just send this simple html file to clients and ask them to run it under IE.


Updated: 1/19/2010
A better way to check .Net Version: Here.

2009/03/25

ASP.Net: Prevent users from submitting a form more than once (disable submit button)

I found an easy way to prevent users from submitting a form more than once. Here is the code
btnSubmit.Attributes.Add("onclick", "this.disabled=true;" +
  ClientScript.GetPostBackEventReference(btnSubmit, "").ToString());
This will disable the button when the submit button is clicked, and it will automatically enable itself after the page has been postback.

Note:
1.The ClientScript.GetPostBackEventReference(btnSubmit, "") will generate the __doPostBack('btnSubmit', ''); for the btnSubmit button.
2.If you use the UpdatePanel control, make sure you update the the submit button as well.
3.It is not 100% working for all situations, so be sure to test it before applying on your web application.

2009/03/12

A simple way to show a popup window (2)

Last time I show how to popup a window if your website supports AJAX, and this time I am going to show you how to do the same thing if your website doesn't support AJAX.
public static void ShowMessage(Page page, string text)
{
  Literal oLiteral = new Literal();
  oLiteral.Text = "<script>alert('" + text + "')</script>";
  page.Controls.Add(oLiteral);
}
Here is how to use:
protected void btnSave_Click(object sender, EventArgs e)
{
ShowMessage(this, "Success!");
}

2009/03/06

A simple way to check special characters by using Regex

using System.Text.RegularExpressions;

public static string CheckString(string text)
{
  Regex oRegex = new Regex(@"[<;/>]+", RegexOptions.IgnoreCase);
  Match oMatch = oRegex.Match(text);
  oRegex = null;

  if (oMatch.Success)
    return "Please do not input any HTML tag";
  else
    return "";
}
Put any character that you want to check inside the "[]".

2009/02/13

A simple way to show a popup window

This is what I use:
private static void ShowMessage(Page page, string message)
{
ScriptManager.RegisterClientScriptBlock(page, page.GetType(),
"IncorrectDate", @"<script>alert('" + message + "');</script>", false);
}
Here is how to use:
protected void btnSave_Click(object sender, EventArgs e)
{
//....
ShowMessage(this, "Success!");
}

PS:Your WebForm must support ASP.Net AJAX (your page must have ScriptManager).

2009/01/25

C#: How to load Excel (xls) and Access (mdb) files (updated: 2012.07.25)

Here is how I load the excel and access files:
1.Includes the name space
using System.Data.OleDb;
2.Set up the connection string
//for xls
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + openFileDialog1.FileName + @";Persist Security Info=True;Extended Properties=EXCEL 8.0";
//for mdb
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + openFileDialog1.FileName + @";Persist Security Info=True";
3.Get the schema
private void GetSchemaTable()
{
  try
  {
    //mdb and xls needs OleDbConnection class, not SqlConnection.
    using (OleDbConnection conn = new OleDbConnection(ConnectionString))
    {
      conn.Open();
      //Fetch all tables' schema. This line is the key point of this method.
      DataTable schemaTable =
        conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });

      //Fetch all tables' name and assign them to comboBox1.
      foreach (DataRow dr in schemaTable.Rows)
      {
        comboBox1.Items.Add(dr[2]);
      }
    }
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message);
  }
}
4.Load table contents
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
  try
  {
    using (OleDbConnection conn = new OleDbConnection(ConnectionString))
    {
      if (String.Equals(FileExtName, "xls"))
        SelectCommand = "SELECT * FROM [" + comboBox1.SelectedItem.ToString() + "]";
      else if (String.Equals(FileExtName, "mdb"))
        SelectCommand = "SELECT * FROM " + comboBox1.SelectedItem.ToString();

      OleDbDataAdapter da = new OleDbDataAdapter(SelectCommand, conn);
      DataTable dt = new DataTable();
      da.Fill(dt);
      dataGridView1.DataSource = dt;
    }
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message);
  }
}

Updated: 2012.07.25
Using parameters:
using (OleDbConnection cnn = new OleDbConnection(
    ConfigurationManager.ConnectionStrings["AccessDB"].ConnectionString))
{
    cnn.Open();
    using (OleDbCommand cmd = new OleDbCommand("Select * From " + comboBox1.SelectedItem + " Where ID = ?", cnn))
    {
        cmd.Parameters.AddWithValue("memberID", mID);
        OleDbDataReader reader;
        reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            ....
        }
    }
}
1. Use the question mark (?) to represent the parameter you want to add.
2. When AddWithValue(), the parameter name doesn't matter. The only thing matter is that if the column type you want to filter is an int (as my example here), the value you gave (mID) has to be able to convert to an int. Otherwise, you will get an error.