<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.csp.uwa.edu.au/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Centre for Software Practice</title><link>http://blog.csp.uwa.edu.au/default.aspx</link><description>the blog</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.2)</generator><item><title>Australia Medicare digital signatures using java and C#</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2009/03/07/australia-medicare-digital-signatures-using-java-and-c.aspx</link><pubDate>Sat, 07 Mar 2009 13:47:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:81</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;So, the problem is how to sign a message using a personal certificate on Australia's Medicare iKey in a browser and being able to verify the signature in a web app. Well, it is more complicated than that but this was the basic problem to start with. &lt;/p&gt;&lt;p&gt;The signing part was relatively simple PKCS#11 using an applet example from Svetlin Nakov (http://www.nakov.com) - the iKey is a SafeNet&amp;nbsp; one (Medicare use a smart card, the 2032, 3000 and 1000 (?) iKey) and comes with a PKCS#11 driver (dkck20.dll).&lt;/p&gt;&lt;p&gt;Note: I did find that the SHA1withRSA didn't work and I used MD5withRSA instead.&lt;br&gt;&lt;/p&gt;&lt;p&gt;The issue was how to verify the signature in C#. I had the X509 public key from the iKey (or you can get it from the &lt;a href="http://www.certificates-australia.com.au/general/cert_search_health.shtml"&gt;Healthcare Public Directory&lt;/a&gt;). Searching for how to initialise the RSA Cryptographic Provider from the X509 certificate took me forever until I hit the magic sequence of terms and it turned out to be surprisingly simple. In .Net 35 there is a class X509Certificate2 which can be initialised from the path name for the public key.&lt;/p&gt;&lt;p&gt;A property of the class, PublicKey.Key gives you an initialised RSACryptoServiceProvider which can then be used to&amp;nbsp; verify the data (specifying MD5 as the hashing algorithm).&lt;br&gt;&lt;/p&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=81" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/RSA+Crypto/default.aspx">RSA Crypto</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/Java/default.aspx">Java</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/X509/default.aspx">X509</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Disabling backspace in forms with Javascript</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2009/01/01/disabling-backspace-in-forms-with-javascript.aspx</link><pubDate>Thu, 01 Jan 2009 08:02:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:68</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;A constant usability issue has been users losing their data entry on forms by inadvertantly pressing the backspace button when the focus is not in a text box or other appropriate control. As very few users realise that backspace has another function in IE to go back a page, this then gets blamed on the web application as a bug. Of the solutions that are out there, the best I found was one posted &lt;a href="http://mspeight.blogspot.com/2007/05/how-to-disable-backspace-in-ie-and.html" target="_blank"&gt;here&lt;/a&gt; which is reproduced below. We use master pages and so it is just put in the master page.&lt;/p&gt;&lt;p&gt;I have seen some posts from over-zealous accessibility people claiming this is a bad thing - changing default browser behaviour. Since most people believe this default behaviour to be fundamentally broken in the case of web applications, I don't think this is a valid critiscism.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Here is the BLOCKED SCRIPT&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;script type="text/javascript"&amp;gt;&lt;br&gt;&lt;br&gt;// Trap Backspace(8) and Enter(13) - &lt;br&gt;// Except bksp on text/textareas, enter on textarea/submit&lt;br&gt;&lt;br&gt;if (typeof window.event != 'undefined') // IE&lt;br&gt;&amp;nbsp; document.onkeydown = function() // IE&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var t=event.srcElement.type;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var kc=event.keyCode;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ((kc != 8 &amp;amp;&amp;amp; kc != 13) || ( t == 'text' &amp;amp;&amp;amp;&amp;nbsp; kc != 13 ) ||&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (t == 'textarea') || ( t == 'submit' &amp;amp;&amp;amp;&amp;nbsp; kc == 13) ||&amp;nbsp; (t == 'password'))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;else&lt;br&gt;&amp;nbsp; document.onkeypress = function(e)&amp;nbsp; // FireFox/Others &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var t=e.target.type;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var kc=e.keyCode;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ((kc != 8 &amp;amp;&amp;amp; kc != 13) || ( t == 'text' &amp;amp;&amp;amp;&amp;nbsp; kc != 13 ) ||&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (t == 'textarea') || ( t == 'submit' &amp;amp;&amp;amp;&amp;nbsp; kc == 13) || (t == 'password')) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;lt;/script&amp;gt; &lt;br&gt;&lt;/p&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=68" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/usability/default.aspx">usability</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/javascript/default.aspx">javascript</category></item><item><title>Failed to Enable Constraints error in DataTables</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/11/19/failed-to-enable-constraints-error-in-datatables.aspx</link><pubDate>Mon, 19 Nov 2007 04:13:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:47</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;This is an error I run into frequently and is frustrating because of course their is no indication of what constraint is being violated. So now I run through the three most frequent problems that will cause this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Having a primary key specified on the DataTable where a query can potentially return duplicates. Sometimes duplicates are unavoidable and so removing the not helpful primary key will sort this one out.&lt;/li&gt;
&lt;li&gt;Finding the columns that have been set to not allow nulls&amp;nbsp; - again, this is sometimes unavoidable and so going through all of the columns and allowing nulls will fix this.&lt;/li&gt;&lt;li&gt;Exceeding the size of a column. This happens if you have created the DataTable and then for some reason alter the column size in the actual database table. The DataTable will not automatically update even if you alter the main query.&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Occassionally I have found that nothing you do will get rid of the problem other than creating the DataTable and queries&amp;nbsp;in a new DataSet (a tedious exercise).&lt;/p&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=47" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/Coding/default.aspx">Coding</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/DataSet/default.aspx">DataSet</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Using multiple MasterPageFiles in an application</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/11/19/using-multiple-masterpagefiles-in-an-application.aspx</link><pubDate>Mon, 19 Nov 2007 04:07:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:46</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;We have an application that we have 2 skins for reflecting the 2 customers of the application. When I went to using skins, I defeined the MasterPageFile in the web.config file rather than switching it programmatically in each page. Unfortunately, this meant that every time I wanted to view a page in Visual Studio 2005, I had to put the MasterPageFile statement back in the page - an extremely tedious problem. Since then, I have discovered that it is relatively easy to set the MasterPageFile in the Page_PreInit method which retains the statement in the aspx file making viewing in the designer still possible. I think this problem is sort of fixed in VS 2008 but switching it programmatically means one less thing that needs to be changed in the config file.&lt;/P&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=46" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/Coding/default.aspx">Coding</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Security decisions – why are they so hard?</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/07/28/security-decisions-why-are-they-so-hard.aspx</link><pubDate>Sat, 28 Jul 2007 11:06:32 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:40</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;We are currently writing an internet-based application for use by doctors and health providers to exchange information. Because of this, security and privacy is obviously a concern (although if the laws around this in Australia were the only guide you may be forgiven for not thinking that!). This has lead to me looking at a number of different possible approaches to keeping the data sent between the users secure and private. The trade of course is quite a few of the other 'ilities like usability, flexibility, mobility, performability (I've always liked that one). Here were the choices with the pros and cons:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;VPN vs SSL: the option of running everything over a VPN was ruled out because we wanted to include a large range of people in a large range of locations – VPNs just don't work in this setting.
&lt;/li&gt;&lt;li&gt;Client certificates: remember the NBT (next big thing)  – PKI? Good because we could have another level of identification – bad because of the overhead of managing certificates, people forgetting their passwords, management of installation or use of the certificates.
&lt;/li&gt;&lt;li&gt;&lt;div&gt;Encryption of data: Generally a good thing because even though the systems administrators could theoretically get access to the keys to un-encrypt, that is a step further than just casually seeing in–the-clear text of messages or data.
&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Public key via client certificates: good because the information is encrypted with the recipient's key – would be even better if this was done on the client – the difficulty is that the only real way of doing this is to use Active X which only works on IE (bad since we support Firefox as well). Bad because of (2) and browser dependencies. If it is done on the server, there is no advantage over symmetric encryption and the overheads are greater.
&lt;/li&gt;&lt;li&gt;Symmetric encryption using a private key: good mostly – another level of protection – the main issue being where to store the key but that can be put on a smartcard or other off-box device.
&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In reality, the decision tree for using a particular variant for security is complicated and the path depends on context. This is probably why it is so difficult to come up with specific recommendations on what is necessary when it comes to security of medical records. The bottom line is that reasonable steps should be made to protect privacy and security of patient information but the advantages to patients of systems that facilitate accurate and timely sharing of information far outweigh the risks of breaches providing a base level of security including SSL, usernames and passwords and content encryption, is applied.&lt;/p&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=40" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/security_3B00_ehealth/default.aspx">security;ehealth</category></item><item><title>Good Error Reporting for ASP.Net Websites with MS-AJAX</title><link>http://blog.csp.uwa.edu.au/tim/archive/2007/07/20/good-error-reporting-for-asp-net-websites-with-ms-ajax.aspx</link><pubDate>Fri, 20 Jul 2007 09:37:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:37</guid><dc:creator>TimHenstridge</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;A requirement in many ASP.Net web applications out there is that you the developer know when your website breaks, the usual way was to use the Application_Error event and then send your self an email or write to a log file.&amp;nbsp; With the event of AJAX itergration into ASP.Net v2.0 the Application_Error event does not run when the request was an Asyncronous PostBack, fear not this is a fixable problem.&amp;nbsp; This article is will cover my personal opinion on a good practice method of error sending. Firstly i will breifly go over the method to run the Application_Error event.&lt;/P&gt;
&lt;P&gt;First Step go to the root of the website and add a new item, add the Global Application Class File leave the file name alone then click Add. you should now have a file Called Global.asax in the root of your website. you can make the Global.asax use a code behind file, which i would recomend.&amp;nbsp; The code for error handling looks something like this:&lt;/P&gt;
&lt;H4&gt;Global.asax:&lt;/H4&gt;&lt;CODE&gt;&amp;lt;%@ Application Inherits="CSP.Global" Language="C#" %&amp;gt; &lt;/CODE&gt;
&lt;H4&gt;App_Code/Global.asax.cs&lt;/H4&gt;
&lt;P&gt;&lt;CODE&gt;using System;&lt;BR&gt;using System.Data;&lt;BR&gt;using System.Configuration;&lt;BR&gt;using System.Web;&lt;BR&gt;using System.Web.Security;&lt;BR&gt;using System.Web.UI;&lt;BR&gt;using System.Web.UI.WebControls;&lt;BR&gt;using System.Web.UI.WebControls.WebParts;&lt;BR&gt;using System.Web.UI.HtmlControls;&lt;BR&gt;using System.Net.Mail;&lt;BR&gt;&lt;BR&gt;namespace CSP&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Summary description for Global&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class Global : System.Web.HttpApplication&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Application_Error(object sender, EventArgs e)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Code that runs when an unhandled error occurs&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExceptionHandling.SendException(Server.GetLastError(), HttpContext.Current);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;&lt;CODE&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;This Code runs a function that sends an error message email to the developers in charge of the application, where the first argument is of type Exception and the second of type HttpContext.&amp;nbsp; The HttpContext.Current object can give us information about the request that caused the error, the session state when it happened, the user who caused the error (via Session state, cookie or IP address, etc) and more.&lt;/P&gt;
&lt;P&gt;On to AJAX exception handling. To my surprise the when an error occured during an AJAX postback the above code never got run so i had to track down what the AJAX alternative was.&amp;nbsp; It was quite simple to find it turned out, the error event seems to be handled by the ScriptManger Control which oddly enough has a OnAsyncPostBackError Event.&amp;nbsp; The point of this post was not my "grand" discovery but rather the best practice method, so back to that.&amp;nbsp; The best way to handle this event was to make sure it was centrally handled once a site was setup and didn't need to be worried about on any subsequent new pages therefore it was perfect to put this into the Master Page.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;In the master page put a scriptmanager in the document body inside the server side form tags like so:&lt;/P&gt;&lt;PRE&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ajax:ScriptManager ID="ScriptManagerMain" runat="server" EnablePartialRendering="true"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OnAsyncPostBackError="ScriptManagerMain_AsyncPostBackError"&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ajax:ScriptManager&amp;gt; &lt;BR&gt;&lt;/PRE&gt;
&lt;P&gt;The code to run the error should look something like this:&lt;/P&gt;&lt;PRE&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void ScriptManagerMain_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CSP.ExceptionHandling.SendException(e.Exception, HttpContext.Current);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;P&gt;Note the event arguments for this event are custom and you can get the Exception Error from them. &lt;/P&gt;
&lt;P&gt;If your website has a combination of these 2 error catching methods you can rest assured that your application is working smoothly whilst running AJAX and that all errors are being reported.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=37" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/tim/archive/tags/asp.net/default.aspx">asp.net</category><category domain="http://blog.csp.uwa.edu.au/tim/archive/tags/ajax/default.aspx">ajax</category><category domain="http://blog.csp.uwa.edu.au/tim/archive/tags/Error+Reporting/default.aspx">Error Reporting</category></item><item><title>10 reasons why programming takes so long</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/07/08/10-reasons-why-programming-takes-so-long.aspx</link><pubDate>Sun, 08 Jul 2007 15:30:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:35</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;[1] The context switch: you are constantly switching between tasks (especially if programming is only one of the jobs you do). Each time you come back to your programming task, you have to remember what you were doing, how you were doing it and what you actually intended to do at the end of it.&lt;/P&gt;
&lt;P&gt;[2] The library/control/feature you are trying to use doesn't work as advertised: You then have to spend time trawling blogs, forums, and yes, even documentation, to try and find out what magic word you forgot to incant!&lt;/P&gt;
&lt;P&gt;[3] You have forgotten how you did it before: the thing design patterns were supposed to fix (ha!) but each time you implement that particular trick feature, you have forgotten how you did and worse still, where you did it last so that you can copy it.&lt;/P&gt;
&lt;P&gt;[4] You are coding with someone else on the same project: so why did they set up that table in that way???&lt;/P&gt;
&lt;P&gt;[5] Procrastination: each time you do [1],[2], [3] (and possibly each of the others) you get side-tracked on the web reading the news&amp;nbsp;or&amp;nbsp;finding out how to do some unrelated feature.&lt;/P&gt;
&lt;P&gt;[6] To do the feature you want to add, you have to change the way everything else works: yes, I know, this was what design (and yes, don't make me laugh, UML) was supposed to fix - but as they say, you don't know until you find out.&lt;/P&gt;
&lt;P&gt;[7] Ajax: everything has to work like gmail.&lt;/P&gt;
&lt;P&gt;[8] Visual Studio/Windows: when it decides it has had enough and simply stops working or forces your computer to arrive at the same conclusion.&lt;/P&gt;
&lt;P&gt;[9] Boredom: you have had enough of this particular project and wished you were back doing open source where there were no deadlines and&amp;nbsp;no users complaining.&lt;/P&gt;
&lt;P&gt;[10] The rest of life: meetings, writing reports, and yes, a little r &amp;amp;&amp;nbsp;r.&amp;nbsp;&lt;/P&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=35" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/software/default.aspx">software</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/programming/default.aspx">programming</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/software+engineering/default.aspx">software engineering</category></item><item><title>Delivering on IT - the abstraction of simplicity</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/06/06/the-it-dilemma-the-tyranny-of-choice-in-a-user-context.aspx</link><pubDate>Wed, 06 Jun 2007 15:17:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:31</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;I was wondering why IT was so hard to do well. Or at least, why so many organisations run into so many problems when dealing with their computing needs. The main thing that seems to paralyze everyone is making a decision. And the reason this is so hard? Like many things, it is because people can't abstract a problem and model it based on the fundamental properties of that problem. Instead, they over-complicate the task by looking only at the individual interconnected parts and then add unrealistic pre-conditions for good measure. This is why the principle of "deliver early and often" works so well. You can start off with a simplified version of the software and through early use and feedback, people get a much better idea of what it is they want, concentrating on the important elements - usually the abstracted core of the system. It also helps if this is also driven by the pragmatism of either small budgets or tight deadlines. &lt;/P&gt;
&lt;P&gt;KISS (keep it simple, stupid), it seems, is a hard lesson to learn, one that has to be reinforced on a regular basis.&amp;nbsp;Achieving simplicity is, as I have said, a product of being able to abstract effectively and then being able to implement a solution which is internally and externally consistent.&lt;/P&gt;
&lt;P&gt;. &lt;/P&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=31" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/reflections+on+IT/default.aspx">reflections on IT</category></item><item><title>the startup lifecycle</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/05/30/the-startup-lifecycle.aspx</link><pubDate>Wed, 30 May 2007 14:30:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:30</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;You decide to start a company. You may even have a business plan, or you have taken the off-the-shelf approach of starting off as a service company with the hope of providing a product which is eventually going to sell in sufficient quantities that it will pay for further development, expansion etc. In the meantime, you are answering the phone, doing the sales, doing the hiring/firing, consultancy and even development. How long does this last? Usually as long as you are prepared to forgo having much of a life outside of it all. The chances of it working out? Not very high. But at least you tried, developed some software and kept some people employed for a while. That can't be a bad thing? And you never know...&lt;/P&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=30" width="1" height="1"&gt;</description></item><item><title>AJAX in ASP.NET 2.0 - Introduction To The Basics</title><link>http://blog.csp.uwa.edu.au/adam/archive/2007/04/17/ajax-in-asp-net-2-0-introduction-to-the-basics.aspx</link><pubDate>Tue, 17 Apr 2007 02:59:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:28</guid><dc:creator>adam.n</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;i&gt;This is a copy of the &lt;a href="http://noizwaves.bur.st/2007-04-16/ajax-in-aspnet-20-introduction-to-the-basics.html" title="Original post on Noiz Waves" target="_blank"&gt;post&lt;/a&gt; on my blog &lt;a href="http://noizwaves.bur.st/" title="Noiz Waves, blog of Adam Neumann"&gt;Noiz Waves&lt;/a&gt;.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/AJAX" title="Wikipedia AJAX" target="_blank"&gt;AJAX&lt;/a&gt;
has become quite the buzzword lately when it comes to Web 2.0. Luckily,
AJAX is really easy to integrate into new and existing ASP.NET
application; it's just a matter of adding some simple controls here and
there. The best thing about AJAX in ASP.NET is that no complex coding
is required; all the postbacks and &lt;a href="http://en.wikipedia.org/wiki/Javascript" title="Wikipedia Javascript" target="_blank"&gt;Javascript&lt;/a&gt; is abstracted away.&lt;/p&gt;
&lt;p&gt;In this article I want to provide a quick introduction to AJAX in
ASP.NET, highlighting core ideas and useful hints, aimed for existing
developers who want to dabble with AJAX. I'm going to start with
installing &lt;a href="http://ajax.asp.net/" title="ASP.NET AJAX" target="_blank"&gt;ASP.NET AJAX&lt;/a&gt;
and configuring Visual Studio 2005 (which takes no time at all). Then
its onto a description of 3 of the main controls that utilise AJAX; the
ScriptManager, UpdatePanel and Timer. Finally, I will create a small
project that combines these controls to perform a simple task.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Installing ASP.NET AJAX&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Firstly, you need to have Visual Studio 2005 and .NET 2.0 installed on your machine. Once you have done this, you need to &lt;a href="http://ajax.asp.net/downloads/default.aspx?tabid=47" title="Download ASP.NET AJAX Extensions" target="_blank"&gt;download the ASP.NET AJAX Extensions 1.0&lt;/a&gt;
(version correct at time of writing). The download is only a couple of
megabytes and provides the essentials for AJAX'ing your websites.
Whilst here, you can also download the &lt;a href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=AtlasControlToolkit" title="ASP.NET AJAX Control Toolkit" target="_blank"&gt;ASP.NET AJAX Control Toolkit&lt;/a&gt;. It provides a large number of AJAX'ed controls which are ready to use.&lt;/p&gt;
&lt;p&gt;Once the extensions have been installed, all that needs doing is
adding the AJAX extensions to the Visual Studio toolbox. I added the
controls to a new tab called 'AJAX Extensions' by right-clicking on the
tab selecting Choose Items and browsing to "C:\Program Files\Microsoft
ASP.NET\ASP.NET 2.0 AJAX
Extensions\v1.0.61025\System.Web.Extensions.dll" then clicking OK. If
all goes well, your toolbox will look like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://noizwaves.bur.st/wp-content/uploads/2007/04/ajax1.png" alt="ASP.NET AJAX 1"&gt;&lt;/p&gt;
&lt;p&gt;That's it! AJAX has been installed, and its ready to be used. If you
want the AJAX Control Toolkit controls in your toolbox, the procedure
is similar, but you browse to "C:\Program Files\Microsoft ASP.NET\Ajax
Control Toolkit\AjaxControlToolkit.dll". Now, onto the controls...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The ScriptManager&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://noizwaves.bur.st/wp-content/uploads/2007/04/ajax2.png" alt="AJAX in ASP.NET 2.0 - Introduction To The Basics"&gt;&lt;/p&gt;
&lt;p&gt;In a nutshell, the ScriptManager is the control that handles most of
the behind the scenes Javascript side of AJAX. There must be a
ScriptManager on any page that uses AJAX. The easiest way to achieve
this is to put one at the top of the &lt;a href="http://msdn2.microsoft.com/en-us/library/wtxbf3hh.aspx" title="Introduction to Master Pages" target="_blank"&gt;master page&lt;/a&gt;.
As far as properties go, EnablePartialRendering is the single most
important one to be familiar with. In a nutshell, it enables or
disables asynchronous postbacks. Disabling partial rendering forces all
postbacks to be full postbacks. This is extremely handy when debugging
some errors, as the error provided with partial rendering is a small
javascript popup.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The UpdatePanel&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://noizwaves.bur.st/wp-content/uploads/2007/04/ajax3.png" alt="ASP.NET AJAX 3"&gt;&lt;/p&gt;
&lt;p&gt;The UpdatePanel is the easiest way to use AJAX to improve the
responsiveness of a web application using AJAX. When an event occurs
that is deemed to be a trigger for the panel, the server processes the
request and responds with the updated contents of the UpdatePanel
INSTEAD of the contents of the entire page. What this means is that
user interactions affecting a small area of the page will only cause
that small area to refresh. This results in a sizable saving of
bandwidth, and a noticeable increase in response time.&lt;/p&gt;
&lt;p&gt;UpdatePanels have a few important parameters that can require
tweaking. ChildrenAsTriggers causes the panel to be refreshed when ever
a child control fires an event. In some situations that is undesirable,
as unnecessary asynchronous postbacks will occur. Triggers is a
collection of control + events pairs on the page that will cause the
update panel to refresh. This is my preferred way to specify when the
contents of the panel are refreshed. UpdateMode specifies whether the
update panel will refresh its contents on any postback or only those
that trigger the panel. Again, I set this to 'Conditional' as it gives
me finer control over when the panel is refreshed.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The Timer&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://noizwaves.bur.st/wp-content/uploads/2007/04/ajax4.png" alt="ASP.NET AJAX 4"&gt;&lt;/p&gt;
&lt;p&gt;This control is one that i had no use for during the first few
months of developing, but after tinkering with the Timer it is
extremely useful in some situations. A Timer fires a Tick event at
regular intervals, and these ticks can be used as triggers for
UpdatePanels. In other words, asynchronous postbacks can occur without
any interaction from the user at all. This would come in handy for
regularly saving the contents of a textbox or loading live stock prices
for example. Timer has a couple of simple but useful properties, and
these are Interval (the delay in milliseconds between tick events being
fired) and Enabled (should the timer fire tick events or not).&lt;/p&gt;
&lt;p&gt;It is possible to get tricky and put a Timer inside an UpdatePanel,
and change the Timer's properties at run time. By setting the Interval
to a very small number, and then immediately disabling the timer in the
tick event handler, only one tick event will occur. This is an
effective way of running a section of code only when the page has
finished loading in the client's browser.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Sample ASP.NET AJAX Website Project&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The sample project I've included with this article uses all three of
the described AJAX controls. It contains a ScriptManager at the top, an
UpdatePanel which contains some labels whose contents will be changed
and refreshed asynchonously, and a Timer to trigger the change in label
text and cause the actual asynchronous postback.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://noizwaves.bur.st/wp-content/uploads/2007/04/ajax5.png" alt="ASP.NET AJAX 5"&gt;&lt;/p&gt;
&lt;p&gt;There is only 2 line of actual C# code in this simple project, and
they set the label text to a random integer. Other than that, no
additional coding was required to implement an AJAX'ed website. Pretty
good eh'?&lt;/p&gt;
&lt;p&gt;From the use of 3 basic controls, anyone can AJAX up their projects,
making them both better to use and more efficient to serve. There are a
couple of other controls included in the ASP.NET AJAX Extensions that I
haven't touched on here; they are the ScriptManagerProxy and
UpdatProgress. I would strongly suggest that everyone muck around with
the UpdateProgress control. From a usability point of view, it is
essential to know when the page is performing behind the scenes, not
just for the users of the site, but also the developers and debuggers.&lt;/p&gt;
&lt;p&gt;Attachments: &lt;a href="http://noizwaves.bur.st/wp-content/uploads/2007/04/sampleajaxwebsite.zip" title="SampleAJAXWebsite.zip"&gt;SampleAJAXWebsite.zip&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=28" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/asp.net/default.aspx">asp.net</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/sample/default.aspx">sample</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/basics/default.aspx">basics</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/updatepanel/default.aspx">updatepanel</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/scriptmanager/default.aspx">scriptmanager</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/ajax/default.aspx">ajax</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/introduction/default.aspx">introduction</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/timer/default.aspx">timer</category></item><item><title>Research-based Practice </title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/03/14/research-based-practice.aspx</link><pubDate>Wed, 14 Mar 2007 03:16:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:26</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;Cross posted from &lt;A class="" href="http://myresearchspace.grs.uwa.edu.au/blogs/davidglanceblog/archive/2007/03/14/research-based-practice.aspx"&gt;myResearchSpace&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;I&amp;nbsp;have recently been looking at issues around best practice in web design. Best practice is often encapsulated as the perceived wisdom of professionals which has become enshrined in the collective mythology of the profession. An example of this in web design is that "users will give up on a website if they have to click more than 3 times"; a hypothesis with no experimental basis and with at least anecdotal research evidence (http://www.uie.com/articles/three_click_rule/) suggesting that it is false (there is little correlation between the number of times a user clicks and a user's successful accomplishment of a task). &lt;/P&gt;
&lt;P&gt;With a growing sense of frustration at not being able to establish the relative credibility of any of the advice that was been given on best practice in web design, I came across a book published by the US Department of Health and Human Services called &lt;A href="http://www.usability.gov/pdfs/guidelines.html"&gt;&lt;STRONG&gt;&lt;FONT color=#749904&gt;Research-Based Web Design &amp;amp; Usabilty Guidelines&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; which uses research findings as the basis for web design guidelines. Apart from being beautifully presented and freely accessible online, it is the methodology used to present the guidelines which is truly impressive. Each guideline within the book is given 2 scores. The first is one for 'Relative Importance' rated by a panel of 16 reviewers, half of which were usability specialists and half web designers. The second score is for 'Strength of Evidence' for each guideline, again rated by a panel of researchers, authors and designers on the basis of a 5 point metric. &lt;/P&gt;
&lt;P&gt;I wonder if there are lessons to be learned from this in the application of presenting research in a thesis? &lt;/P&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=26" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/Website+design/default.aspx">Website design</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/practice/default.aspx">practice</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/research/default.aspx">research</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/Research-based+practice/default.aspx">Research-based practice</category><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/usability/default.aspx">usability</category></item><item><title>Anatomy of a Good Website</title><link>http://blog.csp.uwa.edu.au/david_glances_blog/archive/2007/02/28/anatomy-of-a-good-websites.aspx</link><pubDate>Wed, 28 Feb 2007 04:26:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:25</guid><dc:creator>David.Glance</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;The University of Western Australia's website &lt;A href="http://www.uwa.edu.au/"&gt;http://www.uwa.edu.au&lt;/A&gt; is constantly complained about. In the last user survey, 43% of staff expressed some dissatisfaction with the site. But the site does have lots of good parts to it and has been improving over the past few years as more people become aware of the importance of their web presence. And when compared to other university websites, is it really that different? &lt;/P&gt;
&lt;P&gt;So what is it about the site that doesn't work for its users? Were the issues simply a reflection of a problem at a given point in time that has now been addressed as there are improvements of parts of the website occurring constantly? Probably not. The problems with the UWA website are systemic even though there are numbers of exemplars of good design, content, architecture and usefulness. &lt;/P&gt;
&lt;P&gt;University websites exemplify a type of website that supports multiple "personas" or "role types" in its users. 15 year old school kids will rub shoulders with undergraduates and professors (both UWA and non-UWA) all utilising the website for different purposes. The most common way that websites have dealt with this is either to offer different navigation paths through the same content with or without superficial text around the links giving "user-appropriate" guidance. But it ends up being the same content that they end up with and that may, or may not, be appropriate. &lt;/P&gt;
&lt;P&gt;Looking at the problems of the UWA website and abstracting those to guiding principles for good website design, some general characteristics of good website design has emerged. Although these have resulted in a review of a University website, the principles are general. Applied to a great site like the BBC, all of the principles apply. &lt;/P&gt;
&lt;P&gt;A good website is one that is... &lt;/P&gt;
&lt;P&gt;[1] COHERENT &lt;/P&gt;
&lt;P&gt;Different areas of a website serving the same function to look function in the same way i.e. if you visit the School of Plant Biology's website, it should be structurally similar to the School of Humanities' website. Staff lists should be in the same place with the same details. &lt;/P&gt;
&lt;P&gt;[2] CURRENT &lt;/P&gt;
&lt;P&gt;There is no point in putting information on the web if it is out-of-date or inaccurate. Maintaining the web is a daily activity. &lt;/P&gt;
&lt;P&gt;[3] USEFUL &lt;/P&gt;
&lt;P&gt;The content serves some purpose. It is useful, consistent, discoverable, well written, customised to the reader's persona and meet some need even if this is simply entertainment. &lt;/P&gt;
&lt;P&gt;[4] PERSONALISED &lt;/P&gt;
&lt;P&gt;The experience of the website is tailored to the individual visiting it. The BBC website for example configures the news based on whether you want an International, UK or other perspective. External visitors to the site shouldn't have to navigate or see pages or links that they have no interest or access to. &lt;/P&gt;
&lt;P&gt;[5] DATA-DRIVEN &lt;/P&gt;
&lt;P&gt;Wherever possible, content on the web should be driven out of structured data stored in databases rather than "hard-coded" into web pages. Examples of data-driven web content would be staff lists, research profiles (publications, grants, and research interests), unit, and course information. &lt;/P&gt;
&lt;P&gt;[6] INTERACTIVE &lt;/P&gt;
&lt;P&gt;People interact with a website – the model should be push as well as pull. The website should allow comments, blogs, feeds. &lt;/P&gt;
&lt;P&gt;[7] ATTRACTIVE &lt;/P&gt;
&lt;P&gt;The design should be coherent, attractive, customised, accessible, and follow best-practice design guidelines.&amp;nbsp;Current design stresses simplicity with a content focus.&lt;/P&gt;
&lt;P&gt;[8] RESPONSIVE &lt;/P&gt;
&lt;P&gt;The website should be responsive and make allowance for users with different data access speeds (this can be built into the personalised aspects of the site). &lt;/P&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=25" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/david_glances_blog/archive/tags/Website+design/default.aspx">Website design</category></item><item><title>IE only Stylesheets in ASP websites</title><link>http://blog.csp.uwa.edu.au/tim/archive/2007/02/19/ie-only-stylesheets-in-asp-websites.aspx</link><pubDate>Mon, 19 Feb 2007 02:22:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:24</guid><dc:creator>TimHenstridge</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;a very simple feature i implemented today was to make an IE only style sheet for my application i'm writing it only took 2 lines to make it work.&amp;nbsp; Firstly put the following line in your asp page (best place would be a master page):&lt;/p&gt;&lt;p&gt;&amp;lt;link href="Styles/IEStyle.css" rel="stylesheet" type="text/css" runat="server" id="lnkIEStyle" visible="false" /&amp;gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;this should go after any other style sheets so that it's content takes precedence over the other style sheets.&lt;/p&gt;&lt;p&gt;Secondly put the following line of code (it is in C#) in your page load:&lt;/p&gt;&lt;p&gt;lnkIEStyle.Visible = Request.UserAgent.Contains("MSIE");&lt;/p&gt;&lt;p&gt;this works very well and you can easily make your website look the same across numerous browsers and the method could be used for different browser detection such as if the user agent string contains "gecko" you could single out mozilla based browsers.&lt;br&gt;&lt;/p&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=24" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/tim/archive/tags/stylesheet/default.aspx">stylesheet</category><category domain="http://blog.csp.uwa.edu.au/tim/archive/tags/user+agent/default.aspx">user agent</category><category domain="http://blog.csp.uwa.edu.au/tim/archive/tags/IE/default.aspx">IE</category><category domain="http://blog.csp.uwa.edu.au/tim/archive/tags/asp.net/default.aspx">asp.net</category></item><item><title>Writing Woes</title><link>http://blog.csp.uwa.edu.au/teresa/archive/2007/02/13/writing-woes.aspx</link><pubDate>Tue, 13 Feb 2007 02:03:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:21</guid><dc:creator>Teresa</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;So you've had a beautiful new site created for you by your designer, and all it needs is the content from you to go live. Only problem is it's hard finding time to write it, and soon you realise weeks, even months have gone by and your site is still not live due to lack of content.&lt;/p&gt;

&lt;p&gt;Sound familiar? Don't worry, you're not alone - as designers we've seen (and gently prompted, repeatedly) plenty of clients who have this exact problem. Writing about yourself or your group can be a daunting task and one that is easy to keep putting off until later. Here's a few tips for biting the bullet and getting it done.&lt;/p&gt;

&lt;h4&gt;Put some time aside&lt;/h4&gt;
&lt;p&gt;The first thing you need to do is make some time. This can be hard to do on top of everything else, but is essential - you've obviously already decided that your website is worth some money, time and effort, and putting some time aside to write to bring your new website to completion will be worth it in the long run.&lt;/p&gt;

&lt;h4&gt;Take a look again at your beautiful new design&lt;/h4&gt;
&lt;p&gt;... that your designer has finished, ready to go live as soon as everything else is ready. Doesn't it deserve to be seen? Don't you want to show it to the world? Let it inspire you to do it justice with some quality content! The sooner your part in the process is finished, the sooner people will be able to see it, and you can be sure that a newly design site will have a better impact than an old one, a 'coming soon' page or nothing at all.&lt;/p&gt;

&lt;h4&gt;Look through the suggested structure&lt;/h4&gt;
&lt;p&gt;If your designer has given you some suggestions about the structure of your site based on information you've given them, give it another look through and see if inspiration strikes.&lt;/p&gt;

&lt;h4&gt;Decide on the essentials&lt;/h4&gt;
&lt;p&gt;It helps to start by making a list of what really needs to go up there, especially if your website is a large one. Once you have a rough outline of what you're planning to write it's much easier to begin to flesh it out while keeping in mind the big picture.&lt;/p&gt;

&lt;h4&gt;Look at what other people have done&lt;/h4&gt;
&lt;p&gt;While it's never okay to plagarise someone else's work, taking a look at what your competitors have done can give you some idea of what other people in your industry are doing. Make sure not to copy, but take note of the style, the tone, the kind of things that they mention. Decide what works and what doesn't, and apply those ideas to your own content in your own way.&lt;/p&gt;

&lt;h4&gt;Write for the peoples&lt;/h4&gt;
&lt;p&gt;Some sources might tell you to overload your page's content with commonly searched keywords to ensure a higher search engine ranking. While making sure that you include important things like your name, purpose and location where appropriate can be a good idea, make sure to not lose sight of who you really want to engage with your information - human readers. If your content doesn't make sense or seems repetitive and stilted to a human reader, it doesn't matter how well it does on Google - it won't fulfil it's purpose.&lt;/p&gt;

&lt;p&gt;So get writing and get your site out there! &lt;/p&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=21" width="1" height="1"&gt;</description><category domain="http://blog.csp.uwa.edu.au/teresa/archive/tags/web/default.aspx">web</category><category domain="http://blog.csp.uwa.edu.au/teresa/archive/tags/business/default.aspx">business</category><category domain="http://blog.csp.uwa.edu.au/teresa/archive/tags/communication/default.aspx">communication</category><category domain="http://blog.csp.uwa.edu.au/teresa/archive/tags/writing/default.aspx">writing</category><category domain="http://blog.csp.uwa.edu.au/teresa/archive/tags/clients/default.aspx">clients</category><category domain="http://blog.csp.uwa.edu.au/teresa/archive/tags/content/default.aspx">content</category></item><item><title>Enhanced Calendar with Next/Previous Year Buttons</title><link>http://blog.csp.uwa.edu.au/adam/archive/2007/02/11/enhanced-calendar-with-next-previous-year-buttons.aspx</link><pubDate>Sun, 11 Feb 2007 00:14:00 GMT</pubDate><guid isPermaLink="false">06c7d2c2-7ef8-4788-b25e-93d668b21aa2:20</guid><dc:creator>adam.n</dc:creator><slash:comments>1</slash:comments><description>
&lt;p&gt;By default, Visual Studio 2005 includes a useful range of components for building ASP.NET web applications. Unfortunately these components are usually very basic and have restricted usability, but with a small amount of customisation become highly usable.&lt;/p&gt;

&lt;p&gt;Enter the world of User Controls. A User Control uses regular ASP.NET components as building blocks to construct a more complex control that can be used in the same way as a regular component. User Controls can be assigned their own methods, properties, events, and be drag-and-dropped into ASP pages.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;In this post we will create a User Control that enhances the functionality of the basic Calendar control. We are going to adding buttons that go back and forward 1 year. Clearly when for browsing to dates many years ago or in the future, a simple next/previous month button is not sufficient. To select a date 5 years ago, 5 * 12 = 60 clicks would be required. With the successful implimentation of next and previous year buttons, this could be reduced to 5 clicks. A big win for usability. However, the challange here is where to locate our extra buttons within the user control to achieve a seamless layout. Overriding the Render(HtmlTextWriter) method will allow us to get the best result.&lt;br&gt; &lt;/p&gt;

&lt;p&gt;Also, we will add a nullable SelectedDate property. The SelectedDate property of the standard Calendar must be assigned a value, which means it is difficult to have no selected date. As our SelectedDate can take on a null value (representing no selected date), a simple null check can be used to determine if a date has been selected by the user. As a result of this, form validation just became a whole lot simplier.&lt;/p&gt;

&lt;p&gt;Both the .ascx and .ascx.cs sample code files have been included with this post. Feel free to use these as a basis for adding other enhancements to the standard calendar, or even to start development of your own User Controls.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;First we need to create a new User Control for our enhanced calendar (I suggest creating a new folder called CustomControls and putting it in here). So right click on the destination of the control, select 'Add New Item', choose a Web User Control, and name it EnhancedCalendar. &lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.arach.com.au/%7Evoneuman/pictures/enhancedcalendar/snap01.png" title="Creating the new User Control 1" alt="Creating the new User Control 1" height="125" width="266"&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.arach.com.au/%7Evoneuman/pictures/enhancedcalendar/snap02.png" title="Creating the new User Control 2" alt="Creating the new User Control 2" height="452" width="679"&gt;&lt;/p&gt;

&lt;p&gt;Now we are presented with a blank canvas that is our User Control. From the toolbox, drag over one Calendar control and two link button controls, and give these controls useful names (I have used calDate for the Calendar, btnPrevYear and btnNextYear for the buttons). Change the text for btnPrevYear to "&amp;lt;&amp;lt;"&amp;nbsp; and btnNextYear to "&amp;gt;&amp;gt;" and set both buttons to invisible (as we don't want them to render here). To match the existing interface of the calendar, I gave the buttons a tooltip which describes their function. To handle the selection of a date on calDate, give calDate a SelectionChanged event handler. Finally, give each of the buttons a Click event handler.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.arach.com.au/%7Evoneuman/pictures/enhancedcalendar/snap03.png" title="Design view of the enhanced calendar" alt="Design view of the enhanced calendar" border="1" height="234" width="246"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;That is all we need to do from a design point of view, now we move on to the code behind the scenes. Firstly create a property called SelectedDate, which will allow us to set and
get the date represented by our enhanced calendar. I have chosen SelectedDate to be of
type DateTime? (? makes it nullable) as the standard DateTime type is stored
internally as a primative and thus is not nullable. For the button click event handlers, add or subtract one year from calDate.VisibleDate. Inside the calDate_SelectionChanged handler, we want to update our SelectedDate property with the latest value of calDate.SelectedDate. To be thorough, we should add a method to reset the date on our enhanced calendar, which I have called ResetDate().&lt;/p&gt;

&lt;p&gt;Next we need to alter how our user control is rendered. The procedure we are going to use will follow this basic flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Render calDate to html and store in a string.&lt;/li&gt;

&lt;li&gt;Find the previous month link in the html string, and render btnPrevYear before it.&lt;/li&gt;

&lt;li&gt;Find the next month link in the html string, and render btnNextYear after it.&lt;/li&gt;

&lt;li&gt;Write this string as the html for our user control.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simple.&lt;/p&gt;

&lt;p&gt;The very first thing we need is a way of getting the rendered html code for a control. In our situation we want the html code for calDate. For this we will write a method called RenderToString(Control), which will render a control to html (regardless of its visibility). In theory this method should belong in a utility class, but for this example I have included it in our enhanced calendar's code.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The next things we need are two Regular Expressions that we can use to identify the next and previous month buttons in the stanrdard calendar's html code. By examining the html code of the standard calendar, the previous month button can be isolated by looking for a hyperlink with enclosed text of &amp;amp;lt;, and similarly the next month button by a hyperlink with enclosed text of &amp;amp;gt;. Once the regular expressions have been written, some static Regex objects are constructed to handle the matching.&lt;/p&gt;

&lt;p&gt;Now that we can identify the previous/next month links and render a control to html, we have all the tools required to insert our next/previous year buttons inside calDate. To perform the inserting we use a MatchEvaluator, which works by calling a target method when ever the Regex object finds a match. We will need to make the target method replace the next/previous month html with the next/previous month html concatenated with the rendered next/previous year button. Of course, two different methods are required; one for the next year and one for the previous year, as the order of the buttons is different. I have called these methods AppendPrevYear and AppendNextYear.&lt;/p&gt;

&lt;p&gt;Finally, all that is left to do is perform these steps in the overrided Render(HtmlTextWriter) method. First render calDate to a string, then insert the previous year year button, then insert the next year button, and then write the final html to the writer. And there you have it, that is all the code required to make our enhanced calendar.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.arach.com.au/%7Evoneuman/pictures/enhancedcalendar/snap04.png" title="Original Calendar vs. Enhanced Calendar" alt="Original Calendar vs. Enhanced Calendar" height="253" width="505"&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;With these minor modifications, we now have a more usable (for both developer and end user) calendar control that can be used in the same way as the original. Additionally, it conforms to the same clean and uncluttered layout as the original calendar, which is a bonus. The addition of the next/previous year buttons make this control suitable (when combined with an ajax popup control extender for example) for use as a date selector input for a form. Also, the nullable SelectedDate means that validation of empty required date inputs can occur easily.&lt;/p&gt;

&lt;p&gt;For those readers who want to take this example further, some possible avenues for future development include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expanded the regular expressions to collect the style attribute of the next/previous month hyperlink, and this could also be applied to the next/previous year buttons. This removes the need to synchronise style at compile time, with it instead occuring at run time.&lt;/li&gt;

&lt;li&gt;add a method to the control specifically designed for use with a custom required field validator.&lt;/li&gt;

&lt;li&gt;add more properties that set style attributes of calDate, so style information is not stored in the custom control, and this allow the same control to be used across multiple application.&lt;br&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blog.csp.uwa.edu.au/aggbug.aspx?PostID=20" width="1" height="1"&gt;</description><enclosure url="http://blog.csp.uwa.edu.au/adam/attachment/20.ashx" length="2056" type="application/zip" /><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/next+year/default.aspx">next year</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/validation/default.aspx">validation</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/user+control/default.aspx">user control</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/asp.net/default.aspx">asp.net</category><category domain="http://blog.csp.uwa.edu.au/adam/archive/tags/enhanced+calendar/default.aspx">enhanced calendar</category></item></channel></rss>