Adding Image captcha to BlogEngine.NET

by Kevin Bosch 10. September 2010 09:42

One of the things I liked about BlogEngine.NET is that it had a hidden Captcha feature to mitigate the use of Bots posting comments on the site. However over the last couple of weeks I have noticed a vast increase in amount of bots posting comments and it is getting a little tedious deleting those comments. So I have elected to go add an image Catpcha solution on top of the BlogEngine.NET solution.

The Catpcha solution I ended up using was one derived from http://www.brainjar.com/dotNet/CaptchaImage/ however I elected to use encryption rather than session variables as an academic exercise on how to make it more scalable. More...

Tags: , ,

C#

Select Distinct Values from a .NET DataTable

by Kevin Bosch 5. August 2010 21:19

There are numerous times when it would be handy to have a DISTINCT function to select distinct values out of a datatable used earlier in code. This saves additional round trips to the SQL server. I have used this code in the passed :

private static bool ColumnEqual(object a, object b)
{
    if (a == DBNull.Value && b == DBNull.Value) //  both are DBNull.Value
        return true;
    if (a == DBNull.Value || b == DBNull.Value) //  only one is DBNull.Value
        return false;
    return (a.Equals(b));  // value type standard comparison
}

public static DataTable SelectDistinct(DataTable sourceTable, string columnName)
{
    // Create a new DataTable
    DataTable resultdt = new DataTable();
    // Get the Colunm to use
    DataColumn dc = sourceTable.Columns[columnName];
    if (dc != null)
    {
        // Add a col to the result table
        resultdt.Columns.Add(columnName, dc.DataType);

        // set an object to hold the previous value, and set it value to null fo the first element
        object lastValueAdded = null;
        // get the a sorted list of the results
        DataRow[] sourceDataRows = sourceTable.Select(string.Empty, columnName);
        foreach (DataRow dr in sourceDataRows)
        {
            // if it is the first element or a diffrent value add to the result table
            if (lastValueAdded == null || !(ColumnEqual(lastValueAdded, dr[dc])))
            {
                // set the value for the LastValueAdded
                lastValueAdded = dr[dc];
                resultdt.Rows.Add(new [] { lastValueAdded });
            }
        }
    }
    else
    {
        throw new DataException(string.Format("Column Name {0} Does not exist in SourceTable",
                                               columnName));
    }

    return resultdt;
}

This code is a well know derivative from one at Microsoft. http://support.microsoft.com/default.aspx?scid=kb;en-us;326176#1. The usage is simple as is outlined below:

DataTable Resultdt = DataHelper.SelectDistinct(Sourcedt, "TestCol");
More Examples can be found at Examples using DataHelper.SelectDistinct

The problem with this code was that it did not support multiple distinct fields in a single table. This is a slight drawback for many distinct usages such as drop down lists which typically require value and id.

Rather than rewriting the function above to support multiple fields, I took a closer look at the framework and the distinct functionality is actually wrapped up in the DataView.ToTable Method which was released with .NET 2.0.

Summary usage:

    DataView distinctTableView = new DataView(sourceDataTable);
    DataTable distinctResult;
    // Select Distinct on Col1 and Col2
    distinctResult = distinctTableView.ToTable(true, new[] { "Col1","Col2" });

More comprehensive Examples using a Unit Test

[Test]
public void SelectDistinctValuesExample()
{
    DataTable dt = new DataTable();
    dt.Columns.Add("Col1", typeof (int));
    dt.Columns.Add("Col2", typeof(int));
    dt.Columns.Add("Col3", typeof(int));
    dt.AcceptChanges();

    dt.LoadDataRow(new object[] {1,1,1}, true);
    dt.LoadDataRow(new object[] {1,1,2}, true);
    dt.LoadDataRow(new object[] {1,1,3}, true);
    dt.LoadDataRow(new object[] {1,2,1}, true);
    dt.LoadDataRow(new object[] {1,2,2}, true);
    dt.LoadDataRow(new object[] {1,2,3}, true);
    dt.LoadDataRow(new object[] {1,3,1}, true);
    dt.LoadDataRow(new object[] {1,3,2}, true);
    dt.LoadDataRow(new object[] {1,3,3}, true);

    dt.LoadDataRow(new object[] {2,1,1}, true);
    dt.LoadDataRow(new object[] {2,1,2}, true);
    dt.LoadDataRow(new object[] {2,1,3}, true);
    dt.LoadDataRow(new object[] {2,2,1}, true);
    dt.LoadDataRow(new object[] {2,2,2}, true);
    dt.LoadDataRow(new object[] {2,2,3}, true);
    dt.LoadDataRow(new object[] {2,3,1}, true);
    dt.LoadDataRow(new object[] {2,3,2}, true);
    dt.LoadDataRow(new object[] {2,3,3}, true);

    DataView distinctTableView = new DataView(dt);
    DataTable distinctResult;

    // Example 1 Select Distinct on Col1
    distinctResult = distinctTableView.ToTable(true, new[] { "Col1" });
    // assert result is  
    // 1
    // 2 
    Assert.AreEqual(2, distinctResult.Rows.Count);
    Assert.AreEqual(1, distinctResult.Rows[0][0]);
    Assert.AreEqual(2, distinctResult.Rows[1][0]);


    // Example 2 Select Distinct on Col2
    distinctResult = distinctTableView.ToTable(true, new[] { "Col2" });
    // assert result is  
    // 1
    // 2 
    // 3
    Assert.AreEqual(3, distinctResult.Rows.Count);
    Assert.AreEqual(1, distinctResult.Rows[0][0]);
    Assert.AreEqual(2, distinctResult.Rows[1][0]);
    Assert.AreEqual(3, distinctResult.Rows[2][0]);

    distinctResult = distinctTableView.ToTable(true, new[] { "Col1" , "Col2" });
    Assert.AreEqual(6, distinctResult.Rows.Count);
    // assert result is
    // 1,1
    // 1,2
    // 1,3
    // 2,1
    // 2,2
    // 2.3
    Assert.AreEqual(1, distinctResult.Rows[0][0]);
    Assert.AreEqual(1, distinctResult.Rows[1][0]);
    Assert.AreEqual(1, distinctResult.Rows[2][0]);
    Assert.AreEqual(1, distinctResult.Rows[0][1]);
    Assert.AreEqual(2, distinctResult.Rows[1][1]);
    Assert.AreEqual(3, distinctResult.Rows[2][1]); // only do 6 cells assume rest are correct
}

Tags: ,

C# | DataTable

Cement Expressions as values in a DataTable

by Kevin Bosch 4. August 2010 21:27

I came across a problem the other day which was interesting. Using the SqlDataAdapter it will not allow you to use a field with an expression.; This makes sense as the bulk adapter was built to update a data source which was used to retrieve the data in the first place. As such an expression is simply a calculation of other derived fields and does not need to be saved. In using the SqlDataAdapter for a bulk insert operation one of the fields which was in the source was actually an expression. When trying to run the bulk update from the SqlDataAdapter the code generated the flowing error:

System.InvalidOperationException: The column mapping from SourceColumn 'colname' failed because the DataColumn 'colname' is a computed column.

So to get around this problem I decided to write a procedure to cement the expressions as values pre update. This works much like a copy and paste by values in excel would do. You pass in a datatable which had expression in and it. The code would take the expressions copy the values out into a temp column delete the original column then rename the temp column to the original. The net effect of doing this is that the expressions would be converted to values which could be used in the SqlDataAdapter for a bulk update

The code to Cement Expressions is below:

// gets the first col which has an expression on. // This will need to be refactored if you have expressions based on expressions as you will // need to be aware of dependency order // if no expressions are found it will return null. private DataColumn GetColunmWithExpression(DataTable dt) { DataColumn result = null; foreach (DataColumn dcloop in dt.Columns) { if (!string.IsNullOrEmpty(dcloop.Expression)) { result = dcloop; break; } } return result; } public void CementExpressionsAsValues(DataTable dt) { DataColumn colWithExpression = GetColunmWithExpression(dt); int excapeCounter = 0; while (colWithExpression != null && excapeCounter < dt.Columns.Count) { string tempColName = colWithExpression.ColumnName + Guid.NewGuid().ToString(); dt.Columns.Add(tempColName, colWithExpression.DataType); foreach(DataRow dr in dt.Rows) { dr[tempColName] = dr[colWithExpression.ColumnName]; } dt.Columns.Remove(colWithExpression); dt.Columns[tempColName].ColumnName = colWithExpression.ColumnName; colWithExpression = GetColunmWithExpression(dt); excapeCounter++; } }

Tags: ,

C# | DataTable

Using a CultureScope to switch to a specific Culture for a block of code

by Kevin Bosch 1. February 2009 19:47
The .NET framework provides support for localization. Localization deals with customizing data and resources for specific culture or locale or language. Supporting localization is important for an application if the application is required to be customizable based on the respective culture. Now having to support multiple Cultures invariably means you should be testing your code running under multiple Cultures to ensure it behaves as expected. This is where the concept of the Culture Scope was conceived. Basically using Culture Scope it is possible to define a block of code to run under a specific Culture then revert back when done. Example:

// Set formatString for a currency so we can test diffrent Cultures 
string formatString = "{0:c}";
double TestNumber = 123456.78;

// set the TestCulture to New Zealand 
using (new CultureScope("en-NZ"))
{
    string result = string.Format(formatString, TestNumber);
    // here we assert that the result is formatted with a dollar $
    Assert.AreEqual("$123,456.78", result);
}

// set the TestCulture to English - United Kingdom
using (new CultureScope("en-GB"))
{
    // now make the same call as above with the same parameters.. 
    string result = string.Format(formatString, TestNumber);
    // Now assert the string is formatted with pound £
    Assert.AreEqual("£123,456.78", result);
}

Note the the same code:

string result = string.Format(formatString, TestNumber);
is called twice with different CultureInfo passed to the scope the result is of a function in each scope yields a different result pending the Culture within the given scope The source for the CultureScope is really simple it implements the IDisposable pattern then on creation it keeps a copy of the starting CultureInfo such that it has the ability to roll back on completion. The full source is as follows:

public class CultureScope : IDisposable  
    {
        private CultureInfo _rollbackCulture;

        private void CommonConstructor(CultureInfo cultureinfo)
        {
            if (cultureinfo != null)
            {
                _rollbackCulture = Thread.CurrentThread.CurrentCulture;
                Thread.CurrentThread.CurrentCulture = cultureinfo;
            }
            else
            {
                throw new ArgumentNullException("cultureinfo", "Cannot set a null CultureInfo to the current thread");
            }
        }

        public CultureScope(CultureInfo cultureinfo)
        {
            CommonConstructor(cultureinfo);
        }


        public CultureScope(string Culture) 
        {
            CultureInfo cultureinfo = new CultureInfo(Culture);
            CommonConstructor(cultureinfo);
        }

        public void Dispose()
        {
            Thread.CurrentThread.CurrentCulture = _rollbackCulture;
        }
    }

Tags: ,

C#

Implicit operator

by Kevin Bosch 26. January 2009 08:54

I find from experience on of the least used features in C# is the Implicit operator. The implicit keyword is used to declare an implicit user-defined type conversion operator. This allows the implicit conversion without being specified by explicit casts in the source code. The best way to show this is by way of an example in returning meaningful Boolean results.

For example returning the result from an authentication function often involves checking the result to see it was successful or not. In the case it was not successful giving an indication as to why it was not successful. E.g. expired, locked out, incorrect password, unknown account etc.  

The code is simple for this is simple:

//Source code from the Code Associate C# code library, Full documentation and latest updates can be found
//@ http://www.codeassociate.com/caapi/
using System;
using System.Collections.Generic;
using System.Text;

namespace CA.Common
{

    public struct BoolResultMessage
    {
        public bool Success;

        public string Message;

        public static implicit operator bool(BoolResultMessage result)
        {
            // this the majic that makes the struct work the the if statement.. ie if(BoolResultMessage) ... 
            return result.Success;
        }
    }
}

 

You can find examples on how to use this class at http://www.codeassociate.com/caapi/html/T_CA_Common_BoolResultMessage.htm

Tags:

.NET Development | C#

Calendar

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012 Code Associate