Nov 7, 2016

Iterating over string array in template in SDL Tridion 2013 SP1

Now we can add any string array to template package and iterate over its members in Dreamweaver template. We need to serialize your array and then create package string item out of it as mentioned below:

var list = new[] { "aaa", "bbb", "ccc" };           

StringWriter stringWriter = new StringWriter();
XmlSerializer xmlSerializer = new XmlSerializer(list.GetType());
xmlSerializer.Serialize(stringWriter, list); 

package.PushItem("ItemName",
                  package.CreateStringItem(ContentType.StringArray, stringWriter.ToString()));

The DWT for this array will be as:
  <!-- TemplateBeginRepeat name="ItemName" -->
    <div>@@Value@@</div>
  <!-- TemplateEndRepeat -->

Fixing Chrome resolution issue

There is a very simple solution it fix the chrome resolution issue. Follow the steps below:
  1. Find the Chrome icon that you click on. It may be on the Windows taskbar, a shortcut on the desktop, or in the start menu or on the start screen.
  2. Right-click the icon and select properties from the context menu if the icon is on the desktop or start menu/screen.If it is on the taskbar, right-click Google Chrome in the context menu that opens up and select properties here.
  3. The 'Target' field should end like this afterwards: chrome.exe" /high-dpi-support=1 /force-device-scale-factor=1
Click OK to confirm the change.

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!!