# Wednesday, April 08, 2009

10 Essential Checks before releasing a Web Site

More goodness from Smashing Magazine

This is all fairly well known stuff, but it's amazinf how often I've seen sites go live without 'most' of these.  Now of course every website's different, but this is a great list for reference and for learning.

posted on Wednesday, April 08, 2009 8:02:57 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]
# Monday, March 16, 2009

ASP.NET Data Binding - Accessing a parent data item from within a nested repeater

I'm maintaining an app at the moment that uses quite a few nested repeaters, and found that headers were being output when there was no data present.  It was found that the header was being written in the ItemTemplate of an 'outer' repeater, rather than as the HeaderTemplate of the 'inner' repeater.  The next problem was how to reference the outer repeater from the 'inner' HeaderTemplate...

The following will bind to a field called HeaderDescription.

<%# DataBinder.Eval(Container.Parent.Parent, "DataItem.HeaderDescription") %>

The parent of the inner item is it's repeater, so you have to go to it's parent to get the right RepeaterItem.  Why don't you just do the following you ask?

<%# DataBinder.Eval(Container.Parent.Parent.DataItem, "HeaderDescription") %>

..'cos it doesn't work - The Eval method expects a 'Control' as its first parameter.  There's other ways to do this server-side, but the first option is probably the easiest.

To complete the picture and only show when there's data you can add the following to the 'inner' repeater declaration

OnItemDataBound="ItemDataBound" Visible="false"

then..

        protected void ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item)
            {
                if (!e.Item.Parent.Visible)
                    e.Item.Parent.Visible = true;
            }

        }


This will ensure that you'll only show if you've bound a 'data' item (remember you're doing binding in the HeaderTemplate too).  You could also hook similar things into other events, but it's generally more convenient to put these things into events that relate to the actual control (pre_render's probably another good candidate as it will only get called once and you can check the count in the DataSource).


Technorati Profile
posted on Monday, March 16, 2009 10:28:27 AM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Wednesday, March 11, 2009

Congratulations, you've installed dasBlog with Web Deploy!

After logging in, be sure to visit all the options under Configuration in the Admin Menu Bar above. There are 26 themes to choose from, and you can also create your own.

 

posted on Wednesday, March 11, 2009 6:00:00 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Friday, February 13, 2009

Converting from scientific number format to decimal or string in C#

I'm a programmer, but there are a few things I'll admit I don't do much of (as I have little interest in learning).  Playing with numbers in scientific notation is one of them.

I was importing from a spreadsheet and needed to get "6.00234419836431E+15" to something readable.

I discovered that you need to specify a NumberStyle when you parse as a decimal, because by default you'll get an error as it expects an 'easy' conversion.

The number above had decimals, exponent, the lot - so the following line of code does the job nicely...


Console.WriteLine(decimal.Parse("6.00234419836431E+15", System.Globalization.NumberStyles.Any).ToString());
//Globalisation namespace just shown for clarity - you'll want to put this in a using statement :)


This gives you "6002344198364310". Sweet.

posted on Friday, February 13, 2009 4:39:34 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Thursday, February 05, 2009

Make JQuery and Prototpye coexist and play together with a GreaseMonkey User Script

I've been playing with Greasemonkey scripts recently - for Redbubble.com, and wanted to use JQuery with GreaseMonkey.  This is pretty well documented, but I discovered an incompatibility with my script and the host site, as it uses the Prototype Javascript library (must admit I didn't know much about it).

Prototype (like JQuery) uses the $ notation, and so by default any GreaseMonkey User Script loaded will hijack the $ object, meaning that stuff on the original site may stop working.

I thought I was sunk but it turns out JQuery just gets better, and it can gracefully give back control of the $ to whichever library originally loaded it.  Just call..

jQuery.noConflict();

You then have to use jQuery instead of $ (e.g. jQuery("#myID") instead of $("#myID") ), but hey - that's a small price to pay when the alternative is rewriting the whole thing long-hand.

posted on Thursday, February 05, 2009 9:14:44 AM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Wednesday, January 28, 2009

CommaDelimitedStringCollection - for when you want to write a comma delimited string from a collection !

Amazing that I still find BCL classes every day in .NET to do simple tasks.  I had a feeling that something may exist but didn't expect to find it in the System.Configuration namespace.

using System.Configuration;

CommaDelimitedStringCollection strings = new CommaDelimitedStringCollection();

foreach(string item in myOtherCollection)
{
    strings.Add(item);
}

//Spit out your comma separated string
string output = strings.ToString();

Simple!

posted on Wednesday, January 28, 2009 3:32:30 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [1]
# Monday, January 19, 2009

SANS Institute - Top 25 Dangerous Programming errors

This is really quite interesting.  A lot of stuff that's well known, but a good resource to go back to when you're designing a new system.  There's probably not a system I've ever seen that doesn't exhibit at least one of these in some minor way...

http://www.sans.org/top25errors/

posted on Monday, January 19, 2009 4:09:22 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]

The very reason I write in a blog

Some amusement today as I was trying to set up hibernation on my Windows XP box at work.  I was getting a strange error about 'not enough system resources to complete API'.  After a bit of mucking around I realised I'd actually encountered this very same error a while ago.

I actually used my own blog to fix a problem I'd had before and completely forgot about. 

Funny

posted on Monday, January 19, 2009 3:16:04 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Wednesday, December 31, 2008

Using local SQL 2005 Express databases, |DataDirectory| setting and SQLBulkCopy with SemiColon delimited text files

Had some fun with this today as I was utterly confused why I wasn't able to save data to my SQL2005 express DB (linked within a Windows Forms VS 2005 project), even though I wasn't getting any errors from a SQLBulkCopy operation.  The connection string was set (from the wizard) to use '|DataDirectory|\dbname.mdf.

It turned out of course that the reason there wasn't an error was because the data was being written fine, but just not to the database I was looking at.  By default any database linked in your project file will be copied to the output folder (bin\debug) when you build.  It does this 'every time'.  I thought I was going mad as I wasn't getting primary key violations trying to insert the same data over and over again!

The useful info is in this MSDN blog entry.  It talks about different options for working around the local databases, but I plumped for a subfolder (called data) in my project, then setting 'Copy if newer' on the MDF file rather than 'do not copy'.  This just means that if you make a schema change then it will blow everything away (probably what I normally want in debug-land).

The reason I was using the SQLBulkCopy class was so I could take in a dataset picked from a semicolon-delimited text file. 
The first thing to do was read the text file into a dataset - and after some mucking about with the Jet OleDb provider and avoiding changing registry entries (to get it to recognise ';' as the delimiter) I found that a schema.ini file is what's required.

Here's some quick code I then used to get a DataSet from a semicolon-delimited Text File:

       
       /// <summary>
        /// Import from a given file to database
        /// </summary>
        /// <param name="fileName">File to import from (CSV)</param>
        
public void Import(string fileName)
        {
            
if (File.Exists(fileName))
            {
                SqlConnection connection 
= new SqlConnection(Properties.Settings.Default.RBStatsConnectionString);
                
//Get Dataset from file
                
DataSet importData GetDataSetFromFile(fileName);

                
//Import using SQLBulkCopy
                
SqlBulkCopy copyManager = new SqlBulkCopy(connection.ConnectionString, SqlBulkCopyOptions.UseInternalTransaction);
                
copyManager.DestinationTableName "TShirtStatistic";
                
copyManager.BatchSize importData.Tables[0].Rows.Count;
                try
                
{
                    copyManager.WriteToServer(importData.Tables[
0]);
                
}
                
catch (Exception exception)
                {
                    Console.WriteLine(exception)
;
                
}
                copyManager.Close()
;
                
connection.Close();
            
}


        }

        
public DataSet GetDataSetFromFile(string fileName)
        {
            
//Ensure we've got a schema file to fudge the semicolon delimited text
            
string schemaFile Path.Combine(Path.GetDirectoryName(fileName), "schema.ini");
            
File.Delete(schemaFile);
            string 
schemaContents "[" + Path.GetFileName(fileName) + "]\nColNameHeader=True\nCharacterSet=ANSI\nFormat=Delimited(;)";
            
StreamWriter writer File.CreateText(schemaFile);
            
writer.Write(schemaContents);
            
writer.Close();

            string 
connectionString "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path.GetDirectoryName(fileName) + "\\;Extended Properties='text;HDR=Yes;FMT=Delimited'";
            string 
query "SELECT * FROM " + Path.GetFileName(fileName);
            
OleDbConnection connection = new OleDbConnection(connectionString);
            
OleDbCommand command = new OleDbCommand(query, connection);

            
connection.Open();

            
OleDbDataAdapter adapter = new OleDbDataAdapter(query, connection);
            
DataSet ds = new DataSet();
            
adapter.Fill(ds);

            return 
ds;

        
}
posted on Wednesday, December 31, 2008 11:40:27 AM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]