Thursday, March 30, 2006

Blog Moved

Today I got thinking about where to host my blog again. This time I decided to actually do something about it. I am going with blogspot. Fortunately I used a feedburner feed which I have now redirected. Anyway its good to finally have a place where this can live without worrying about if it is going to be around next week...

Using Full Text Searching with SQL Server

The MurrayBookshop allows users to search for books using SQL Servers Full Text Searching. This works resonably well but could be better.

Currently we use a constructed SQL string that is run via sp_executesql. This is required as we perform paging using SELECT TOP x, where x is a variable based upon the page selected, and the number of records per page. With SQL Server 2005 the SELECT TOP command now allows a variable number of records to be selected so this can then be re-designed to be much simpler.

The other problem is that uses may type anything into the search box. Unfortunatly the full text search does not allow any text to be used to perform the select. To overcome this you need to watch for two errors when using Fill from a SqlAdapter. (base.FillDataSet uses a SqlDataAdapter with the passed in command).

try
{
base.FillDataSet(newData, _BrowseCommand);

return new ProductBrowseResponse(request, newData, (int)_BrowseCommand.Parameters["@TotalPages"].Value, (int)_BrowseCommand.Parameters["@TotalProducts"].Value, ok);
}
catch(SqlException e)
{
if(e.Number == 7619 || e.Number == 7603)
{
return BrowseProductsWithoutSearch(request);
}
else
{
throw new DatabaseTechnicalException("Error browsing for products", Connection.ConnectionString, e);
}
}
A cutdown version of the select command is shown below. This selects the second page of 10 records that match the text in @SearchStringSQL.

SELECT Product.[ProductCode], Product.[ProductTitle], [Rank]
FROM [Product]
INNER JOIN
( SELECT ProductCode, ProductTitle, Rank
FROM
( SELECT TOP 10 ProductCode, ProductTitle, Rank
FROM
( SELECT TOP 20 [Key] As ProductCode, ProductTitle, Rank
FROM FREETEXTTABLE(Product, ProductTitle, @SearchStringSQL) AS KEY_TBL
INNER JOIN Product ON KEY_TBL.[Key] = Product.ProductCode
ORDER BY Rank DESC, ProductTitle ASC
) AS Table1
ORDER BY Rank ASC, ProductTitle DESC
) AS Table2
) AS TABLE3 ON Table3.ProductCode = Product.ProductCode
ORDER BY Rank DESC, Product.ProductTitle ASC;

The BrowseProductsWithoutSearch performs the same query without the full text search.

Password Strength Indicator

(Apologies for the format of this post)
(Feel free to use this, but if you do please let me know)

The other day I registered a friend with MSN Messenger and was impressed by their password strength indicator. Today I decided to implement my own. The results are below.

Basically I use a regular expression to evaluate the strength of the password. Weak = 6 characters at least, Medium = a combination of characters, and numbers, Strong = combination of characters, numbers, and special characters.




The JavaScript is:

<script language="javascript">
var ieDOM = false, nsDOM = false;
var stdDOM = document.getElementById; function initMethod()
{
//Determine the browser support for the DOM
if( !stdDOM )

{
ieDOM = document.all;

if( !ieDOM )

{
nsDOM = ((navigator.appName.indexOf('Netscape') != -1) && (parseInt(navigator.appVersion) ==4));
}
}

passwordChanged();
}

function getObject(objectId)

{
if (stdDOM) return document.getElementById(objectId);
if (ieDOM) return document.all[objectId];
if (nsDOM) return document.layers[objectId];
}

function getObjectStyle(objectId)

{
if (nsDOM) return getObject(objectId);

var obj = getObject(objectId);

return obj.style;
}

function showDefault(objectId)

{
showCell(objectId, "#E2E2E2", "#E2E2E2");
}

function showCell(objectId, foreColor, backColor)
{
getObjectStyle(objectId).color = foreColor;

getObjectStyle(objectId).backgroundColor = backColor;
}

function showWeak()

{
showCell("pwWeak", "Black", "#FF6666");

showDefault("pwMedium");

showDefault("pwStrong");
}

function showMedium()

{
showCell("pwWeak", "#FFCC66", "#FFCC66");
showCell("pwMedium", "Black", "#FFCC66");

showDefault("pwStrong");
}

function showStrong()

{
showCell("pwWeak", "#80FF80", "#80FF80");
showCell("pwMedium", "#80FF80", "#80FF80");
showCell("pwStrong", "Black", "#80FF80");
}

function showUndetermined()

{
showDefault("pwWeak");
showDefault("pwMedium");
showDefault("pwStrong");
}


function passwordChanged()
{
var strongRegex = new RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g");
var mediumRegex = new RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$", "g");
var enoughRegex = new RegExp("(?=.{6,}).*", "g");


var pwd = getObject("txtPassword").value;
if( false == enoughRegex.test(pwd) )
{
showUndetermined();
}
else if( strongRegex.test(pwd) )
{
showStrong();
}
else if( mediumRegex.test( pwd ) )
{
showMedium();
}
else
{
showWeak();
}
}
</script>



The password strength indicator table is:

<TABLE style="BORDER-RIGHT: black thin solid; BORDER-TOP: black thin solid; FONT-SIZE: 75%; BORDER-LEFT: black thin solid; BORDER-BOTTOM: black thin solid"

cellSpacing="0" cellPadding="0" width="100%">

<TR>

<TD id="pwWeak" style="BORDER-RIGHT: black thin solid" align="center" width="34%" title="Has at least six characters">Weak</TD>

<TD id="pwMedium" style="BORDER-RIGHT: black thin solid" align="center" width="33%" title="Has a mix of numbers, lower & upper case characters.">Medium</TD>

<TD id="pwStrong" align="center" width="33%" title="Has numbers, special characters, lower & upper case characters.">Strong</TD>

</TR>

</TABLE>



And this required an action to be added to the txtPassword. As this is ASP.NET we use the following in the page load event for the class:

txtPassword.Attributes.Add("onKeyUp", "passwordChanged()");

Hiding controls in ASP.NET

If you use control.visible = false for controls in your web application these will not be rendered to the resulting HTML. If you want to interact with the control via Javascript there are going to be problems...

Fortunatly one of my Enterprise .NET students found a potential solution. Try the following in your web applications:

control.Style.Add("display","block"); // makes visible
control.Style.Add("display","none"); // makes invisible

Thanks for finding this solution.

The following script can be used to show and hide controls based on the state of a checkbox.

<script language="javascript">
var ieDOM = false, nsDOM = false;
var stdDOM = document.getElementById;

function initMethod()
{
//Determine the browser support for the DOM
if( !stdDOM )
{
ieDOM = document.all;

if( !ieDOM )
{
nsDOM = ((navigator.appName.indexOf('Netscape') != -1) && (parseInt(navigator.appVersion) ==4));
}
}

checkedChanged();
}

function getObject(objectId)
{
if (stdDOM) return document.getElementById(objectId);
if (ieDOM) return document.all[objectId];
if (nsDOM) return document.layers[objectId];
}

function getObjectStyle(objectId)
{
if (nsDOM) return getObject(objectId);

var obj = getObject(objectId);
return obj.style;
}

function show(objectId)
{
var objs = getObjectStyle(objectId);
objs.visibility = 'visible';
}

function hide(objectId)
{
var objs = getObjectStyle(objectId);
objs.visibility = 'hidden';
}

function checkedChanged()
{
var chkBox = getObject('chkBox');

chkBox.checked ? show('txtCreditLimit') : hide('txtCreditLimit');
}
</script>

initMethod() must be called when the page loads: <body onload="initMethod();">

You also need to add some code to the page load to register the checkChanged with the click event on the checkbox. chkBox.Attributes.Add("onclick", "checkedChanged();");

This then allows the control to be shown and hidden using client side Java script.

Monday, March 20, 2006

.NET Job

Another past student contacted me looking for a .NET developer. Here is what they asked me to post:

Full time positions are available at InsuranceLine for a .NET developer with the following requirements.

The ideal candidate would have experience working on a distributed application in .NET, with the following skills summarized below.
1. Excellent command over the VB.net language.
2. Implementation knowledge and exposure to Microsoft multi-layer/tier application architecture model for distributed .net Apps.
3. Experience and excellent command over SqlServer 2000 client tools and TSQL.
4. Expereince with writing unit tests in nUnit.
5. Experience of debugging, testing and writing serviced components in COM+.

Also desirable skills include
1. Exposure to VS 2005.
2. Microsoft Application blocks for .NET (UIPAB in particular)
3. Experience in various common patterns of Enterprise Architecture.
4. Managing Security, roles, and permissions in a distributed application in COM+.

Resumes + Cover letters can be forwarded at afif.mohammed@mel.insuranceline.com.au

Monday, March 13, 2006

XBox 360

Am I hanging out for this or what... I have the premier pack and this weekend I cracked. I opened all of the packaging and drooled over the bits. The controller is much lighter than I thought it would be, but unfortunately pointing it at my tv and pushing the buttons did nothing :). Anyway only a few days to go now... Much keep repeating that to get myself...

The game looks good and the manual is interesting... well thats all I can do with it at the moment.

Cant wait!

Thursday, March 09, 2006

Week 2 well under way

I am almost ready for HIT1301 now :) and its only half way through week 2. I have finally finished the labs, and got the basic outline for the material on SwinBrain. Now its time to see how this is going to go...

I have finished all of my HIT1301 (Algorithmic Problem Solving) tutorials for this week and for the most part they were quite good. This week we looked at reading and understand source code (with a little bit of coding for fun). Most of the students are prepared to give it a go, and I hope they had some fun with the exercises. My favorite exercise from this week was the program to make the screen flash red, green, then blue. It only takes a few lines of code, but this is much more interesting than just printing text to the screen. I must say that everything is much easier and more interesting when you dont have to deal with objects and the like.

Next week there is a quiz, so I'll have a bit better idea how people are going after that.

Monday, March 06, 2006

Teaching again

The "teaching period" (aka semester) started last week and labs have started this week. Both of my subjects have started well. I am teaching Algorithmic Problem Solving and Enterprise .NET. The two ends of the programming spectrum at Swinburne. Algorithmic Problem Solving (APS) is an introductory subject where students are learning to read and understand code at the moment, and will soon move to writing code and solving problems. Enterprise .NET is Enterprise .NET :) we will start looking at developing multi-layered software, and database programs this week.

APS is a totally new subject, and it is always interesting to see how the new material works out. It appears to be going well so far, though I'm sure its either to fast or to slow. Student who have programmed before will find the start a little slow, while for the new programmers we are covering a lot of new material in a short time.

Today I had my first APS labs. The lectures are always hard to judge, but the labs really give you a feel for how everyone is progressing. So far most students are going well. I have had a few new programmers "get it" for a number of new concepts.

As far as challenge goes, we are already looking at procedures and functions in code, as well as working with the different control flow statements. These concepts are core and once covered we can start writing more interesting code. Having said that most other introductory programming subjects would not have covered so much by week 2... Lets hope it all goes well... If you are doing this subject and feel "up to date" you are doing really well. If not keep reading and ask questions.