Jun 13, 2016

Catching JavaScript Errors with window.onerror

First we need to override the handler as:

window.onerror = function (errorMsg, url, lineNumber) {
    console.log('Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber);
}

We can add two more variables to get more information: column number and error object.

window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
    console.log('Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber 
    + ' Column: ' + column + ' StackTrace: ' +  errorObj);
}

Note: This will work only in the latest browsers.

Feb 8, 2016

Encrypt in SQL Server and Decrypt in C#

Recently, I had a requirement to fetch the encrypted string passed from SQL Server using function EncryptByPassPhrase (more details about this function here). This encrypted string was passed from a totally different setup to my ASP.Net web application.

My ASP.Net web Application required the decoded text. To do this I had to create a stored procedure which accepted the pass phrase and encrypted string as input and returned the decrypted string. The encrypted string type was VARBINARY. The stored procedure was:
CREATE PROCEDURE [dbo].sp_DecryptText 
    (@PassPhrase NVARCHAR(128), 
    @EncryptedText VARBINARY(MAX),
    @DecryptedText NVARCHAR(MAX) OUTPUT)
AS
BEGIN
    SET @DecryptedText = DECRYPTBYPASSPHRASE(@PassPhrase, @EncryptedText);
    RETURN
END
So I wrote a C# code to connect to stored procedure passing all the values as:
command.Parameters.AddWithValue("@PassPhrase", PassPhrase);
command.Parameters.Add("@EncryptedText", SqlDbType.VarBinary, 8000).Value = Encoding.Unicode.GetBytes(encryptedString);
command.Parameters.Add("@DecryptedText", SqlDbType.NVarChar, -1).Direction = ParameterDirection.Output;
But this did not work as the encryptedString was already in hexadecimal format and converting it to bytes resulted in a totally different string.

To get the stored procedure working, I converted the encryptedString to hexadecimal before passing it to the stored procedure by writing a separate function ParseHexString as:
static byte[] ParseHexString(string value)
{
    if (string.IsNullOrEmpty(value)) return null;
    if (1 == (1 & value.Length)) throw new ArgumentException("Invalid length for a hex string.", "value");

    int startIndex = 0;
    int length = value.Length;
    char[] input = value.ToCharArray();
    if ('0' == input[0] && 'x' == input[1])
    {
        if (2 == length) return null;
        startIndex = 2;
        length -= 2;
    }

    Func<char, byte> charToWord = c =>
    {
        if ('0' <= c && c <= '9') return (byte)(c - '0');
        if ('A' <= c && c <= 'F') return (byte)(10 + c - 'A');
        if ('a' <= c && c <= 'f') return (byte)(10 + c - 'a');
        throw new ArgumentException("Invalid character for a hex string.", "value");
    };

    byte[] result = new byte[length >> 1];
    for (int index = 0, i = startIndex; index < result.Length; index++, i += 2)
    {
        byte w1 = charToWord(input[i]);
        byte w2 = charToWord(input[i + 1]);
        result[index] = (byte)((w1 << 4) + w2);
    }

    return result;
}

So my call to stored procedure changed to:
command.Parameters.AddWithValue("@PassPhrase", PassPhrase);
command.Parameters.Add("@EncryptedText", SqlDbType.VarBinary, 8000).Value = ParseHexString(encryptedString);
command.Parameters.Add("@DecryptedText", SqlDbType.NVarChar, -1).Direction = ParameterDirection.Output;
And the output was correct and in the right format!!


Oct 31, 2015

Change Creation Date of file to Modified Date using PowerShell

Use the following PowerShell command to change the Creation Date to the Modified Date of all files in a folder.

Get-ChildItem -recurse -filter *.JPG | % { $_.CreationTime = $_.LastWriteTime }

Oct 8, 2015

Rename all files replacing a text using PowerShell

Let's say you have a number of files at location C:\demo with text "OldValue" in it. And you want to replace text "OldValue" to "NewValue" in all files. To do that follow the steps below:

  1. Open Windows PowerShell.
  2. Navigate to location C:\demo
  3. Run the following Windows PowerShell command: 
    Get-ChildItem -Filter "*OldValue*" -Recurse | Rename-Item -NewName {$_.name -replace 'OldValue','NewValue' }
  4. All files will be renamed.

  • The command Get-ChildItem -Filter "*OldValue*" finds all files with the string "OldValue" anywhere in the name.
  • Get-ChildItem searches recursively through all subfolders.
  • | (the pipe character) instructs Windows PowerShell to take each item (object) found with the first command (Get-ChildItem) and pass it to the second command (Rename-Item)
  • Rename-Item renames files and other objects.
  • {$_.name -replace 'OldValue','NewValue' } instructs Rename-Item to find the string "OldValue" in the file name and replace it with "NewValue"

Sep 17, 2015

Printing all properties of an Object

To write all the properties and such of an object to the console (or log or to front end), use TypeDescriptor class.

foreach(System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(obj))
{
    string name=descriptor.Name;
    object value=descriptor.GetValue(obj);
    Console.WriteLine("{0}={1}",name,value);
}

Where obj is the class for which properties are to be printed.

Sep 15, 2015

Creating a custom class in C# for creating a log file

Code for the class to create log file:

Local SMTP server for Testing and Development on Windows

Use Papercut.

Download the application and run it. It will set up an SMTP server when it's running. Configure your application to use 'localhost' (or the machine where the server is running) as the SMTP server. If you need to use a non-default port number, you can configure it in Options.

As per the CodePlex webpage:
Papercut is a simplified SMTP server designed to only receive messages (not to send them on) with a GUI on top of it allowing you to see the messages it receives. It doesn't enforce any restrictions on addresses, it just takes the message and allows you see it. It is only active while it is running, and if you want it in the background, just minimize it to the system tray. When it receives a new message, a balloon message will show up to let you know.