Thursday, December 17, 2009

YQL, Pipes and beyond

I've recently fallen in love with Yahoo again

Inspired by Haayman (a runsat user) I've been using Yahoo pipes to manipulate the site RSS output into more human friendly form.

The latest bit of this is here: -

Inspired by this pipe just shows how developed the web is now...

- it gets data from runsat
- processes that data
- makes a call to YQL which then processes the data through this serverside javascript - (this converts a google maps API
- processes the data some more
- spits out some new RSS which can then be consumed by web pages - e.g. by

Of course, all of this could also be seen as fragile - it relies on external web services, but these are all on Yahoo! - so not too fragile (I hope!).

The programmable web - I love it!

Sunday, December 13, 2009

More player code live on runsaturday

A "simple" player:

A player with side map and elevation/speed chart:

Tuesday, November 17, 2009

"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."

If you're working late at night and suddenly you start seeing lots of https issues concerning... "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."

Then it might just be because your app is routing its requests via the excellent fiddler2 - in which case SSL will not be trusted :)

Monday, November 16, 2009

Hard disk thrashing on Vista

I've been struggling recently with far too much hard disk thrashing.

So I searched around for help, and I've no idea if their advice helps yet, but this article seemed at least well written:

Let's hope it helps - because recently the hard disk action has been way too slow!

Super easy to use (and free) POP3 email client source code

Really good project!

Super easy to follow walkthrough for creating a custom DNN scheduled task

Super easy to follow walkthrough for creating a custom DNN scheduled task -

Really good stuff

Wednesday, November 11, 2009

Visual Trace Route

Just found this on the web. It wasn't what I was looking for - but it's a cool toy - let's you see some cute tracert maps

Would be fabulous if they could actually use my tracert results rather than their results.

Tuesday, November 10, 2009

JSON and cross site scripting

Been doing quite a lot of JSON work recently.

Have hit the odd occasion where I've needed to get JSON data across domain boundaries.

To do this, the only way seems to be to make use of <script> tags rather than making use of simple (e.g. Jquery) xml/http get's.

Basically what you do is:

1. Define a callback method, e.g.:

function myCallback(data)
// do stuff

2. On the server, instead of returning JSON, return the JSON inside a callback call, e.g.:
myCallback({ "thing": 12 });

3. To make the ajax call, then add a script tag to the document head:
            var scriptBlock = document.createElement('script');
            scriptBlock.src = jsonUrlToCall;
            scriptBlock.type = 'text/javascript';

4. Actually, that's it!

Tuesday, November 03, 2009

Samsung Omnia 2... GPS - the only setttings that work

More about this another day...

But have wasted so much time on trying to get Samsung Omnia II to hook up to GPS today...

Whatever you do, don't change the default settings:

Go to setting --> General Setting --> GPS --> Connection 
GPS program port: com7
GPS hardware port:com9
Baud rate: 4800
Click on done.
Go to XTRA
Enable XTRA Server
Tick "ZWhen connected to PC via ActiveSync
Enable SNTP Server (Only when you have data plan)
Click done.

These settings work!

Some color code to make some javascript HTML colors darker

I needed to quickly produce some new darker colours for an array of html colors.

Using this:

I built this:
    <div id='outputLifeLine'>
    <script type="text/javascript">
        var arr = [[-18, '#00ff00'],
        [-4, '#aaff00'],
... snip...
        [18, '#ff2200']];

        var G = {}, $ = function(a) { return document.getElementById(a) };

        G.color = {
            rgb: function(a) {
                var o = a.toLowerCase();
                return [parseInt(o.slice(0, 2), 16), parseInt(o.slice(2, 4), 16), parseInt(o.slice(4), 16)];
            shade: function(a, b) {
                var v = [], i;
                for (i = 0; i < 3; i++) {
                    v[i] = Math.round(a[i] * b)
                    if (v[i] > 255) v[i] = 255
                    if (v[i] < 0) v[i] = 0
                return v
            hex: function(a) { var f = G.color._hex; return f(a[0]) + f(a[1]) + f(a[2]) },
            _hex: function(a) { return ('0' + a.toString(16)).slice(-2) }

        var txt = '';
        var m = G.color;
        for (var i in arr) {
            var n = m.rgb(arr[i][1].substr(1));
            txt += "[" + arr[i][0] + ",'" + arr[i][1] + "', '#" + m.hex(m.shade(n, 0.6)) + "'],";
            txt += "<br/>"
        var d = document.getElementById("outputLifeLine");
        d.innerHTML = txt;


And then ran it... Nothing special... but thought I'd share it!

Monday, November 02, 2009

The perils of Javascript - Number.MIN_VALUE

Just spent some time debugging a problem....

I had a filter set up in my new player code on runsat - and when the filter was disabled I was setting the filter limits to Number.MIN_VALUE and Number.MAX_VALUE.

When a calculation results in a number greater than Number.MAX_VALUE, it is assigned a value of Number.POSITIVE_INFINITY.

When a calculation results in a number less than Number.MIN_VALUE, it is assigned a value of Number.NEGATIVE_ INFINITY.

However.... this is complete "codswollop" - actually MIN_VALUE is an epsilon value - it's the smallest positive fraction allowed in javascript - so it's not negative - in fact it's almost (but not quite) zero.

Looking around loads of sites contain big info on this!


Friday, October 16, 2009

DNN - installing AjaxToolkit ahead of UKNuke RPX authentication

These were the draft steps I wrote about how to install the popup login functionality...

This is still in development... not really ready for primetime yet!


1. AjaxToolkit

You need the AjaxToolkit installed within your DNN bin folder. This can be downloaded from To install it you may also need to update your System.Web.Extensions.dll to a more recent version (and indeed you may need to update the whole portal to .Net 3.5). 

I can't assist you with this part in detail here - but there are quite a few links/instructions out there on Bing/Google!

One thing that helped me was updating web.config to include this "bindingRedirect" section:
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="" newVersion="" />
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="" newVersion="" />

- this taken from a DNN 5.1.4 example portal.

2. Install the new RPX module I just sent you

3. Change your skin

You'll need to add this to the top of your skin:
<%@ Register TagPrefix="uknuke" TagName="Login" Src="~/DesktopModules/AuthenticationServices/UkNuke.RPX/LoginButton.ascx" %>

And you'll need to add this wherever you want the login link to appear:
<uknuke:Login ID="specialLogin" runat="server"></uknuke:Login>

4. That should be it :)

Some difference in DNN 5.1.4 - logging into SQL2005

For some reason my old connection strings - which started "Server=(local);" no longer work in DNN 5.1.4

Basically, the connection string now starts "(local);" 

Thursday, October 15, 2009

Getting AjaxToolkit to work in an old project

I was trying to update an old DotNetNuke project so it would use the AjaxToolkit.

To do this I had various problems with System.Web.Extensions versioning.

After some pain, I discovered one solution was to add this section to the web.config file :)

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="bin;bin\HttpModules;bin\Providers;bin\Modules;bin\Support;" />
 <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
 <bindingRedirect oldVersion="1.0.61025.0" newVersion=""/>
 <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31BF3856AD364E35" culture="neutral"/>
 <bindingRedirect oldVersion="" newVersion=""/>

Tuesday, October 13, 2009

Finding a table name

I knew my table had "comment" in it... so I used this to find out the table name

FROM dbo.sysobjects

I could also have used xtype:
'V' - views
'S' - system tables

From: - thanks!

Tuesday, October 06, 2009

SagePay processing for nopcommerce - my first codeplex launch

Spent lots of today coding a SagePay payment processor for NopCommerce.

The details of it are on cirrious at:

And I've launched it as a codeplex project at:

Overall I'm quite impressed with the support info available at - and their simulator is very useful for testing.

Friday, September 25, 2009

Creating an ActiveX object and running it in a browser

I'm such an old fuddy duddy... that I'd never really tried COM wrapping on C# objects.

But today all that changed...

This blog post helped lots:

I'll try to actually post the code on this later... it's a nice way of extending a web app in an Intranet environment (it's not for Internet...)

Saturday, September 12, 2009

An excellent explanation of the confusion that reigns between ASP.Net 2.0 and 3.x

This is something I've come across more than once now - people complaining their ASP.Net 3.5 applications are running as 2.0 and not being able to set them in IIS...

Here's a superb explanation of what 3.0 and 3.5 added to 2.0 - and how they did it without changing the core runtime

Monday, September 07, 2009

Adding direct SQL editing/browsing access to any website...

I was editing a nopcommerce website that I only had http and ftp access to - no sql access.

So I needed a way to execute some SQL scripts.

To do this I added (to the administration pages) the following

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SQLRunner.aspx.cs" MasterPageFile="~/Administration/main.master" Inherits="NopSolutions.NopCommerce.Web.Administration.SQLRunner" %>

<asp:Content ID="Content1" ContentPlaceHolderID="cph1" runat="server">
    <br />
    <asp:TextBox ID="tbSQL" runat="server" Columns="80" Rows="10" TextMode="MultiLine">
    <br />
    <asp:CheckBox ID="cbScript" runat="server" Text="Run as script" />
    <asp:Button ID="btnGo" runat="server" Text="Go" OnClick="btnGo_OnClick" />
    <br />
    <asp:Panel ID="pnlOutput" runat="server" Visible="false">
        <asp:GridView ID="grdResults" runat="server"></asp:GridView>
    <asp:Label ID="lblResult" runat="server" >

coupled with this source

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using NopSolutions.NopCommerce.Web;
using NopSolutions.NopCommerce.DataAccess;
using System.Configuration;
using System.Data.SqlClient;

namespace NopSolutions.NopCommerce.Web.Administration
    public partial class SQLRunner : BaseNopAdministrationPage
        protected void Page_Load(object sender, EventArgs e)


        protected void btnGo_OnClick(object sender, EventArgs e)
                var sqlConnection = NopSqlDataHelper.CreateConnection(ConfigurationManager.ConnectionStrings["NopSqlConnection"].ConnectionString);
                var sqlCommand = sqlConnection.GetSqlStringCommand(tbSQL.Text);
                if (cbScript.Checked)

                    pnlOutput.Visible = false;
                    var dataSet = sqlConnection.ExecuteDataSet(sqlCommand);

                    pnlOutput.Visible = true;
                    grdResults.DataSource = dataSet;
                lblResult.Text = "OK";
            catch (Exception exc)
                lblResult.Text = string.Format("Exception seen - {0} - {1}", exc.GetType().Name, exc.Message);

Seems to work OK :)

Some interesting projects on codeplex

Just did a quick troll through the list of some of the more popular projects on codeplex - just to see what was on there.

These are some of the things that caught my eye.

Cosmos - open source operating system for C# -

GPS Tracka - - looks good!
TravelPoint - windows mobile GPS location -

Silverlight Media Player -

Quick Query Editor -

A bit DNN Help desk module -
Some DNN SKins -

BugTracker.Net - and
CSharp Parser -
Code review -

Kigg - interesting site - and

CMS stuff - -
CMS stuff -
CRM project -
WikiPlex -

DinnerNow sample app -

Google Map control - and
Geo Framework -
Deep Earth - Silverlight mapping -
Google maps in winforms -

Thursday, September 03, 2009

ASP.Net AJAX problems - Gray Google Maps

While adding some google map functionality to a custom nopcommerce build I came across some "gray map of death" problems with the gmaps. Basically the maps seemed to be offline - they didn't draw properly and they didn't respond correctly to mouse events (double click or drag).

Searching, I found a few references to these sorts of problems - most of which seemed to be caused by css issues (float:left seemed to be a common cause).

However, eventually this thread showed me the way forwards -

Basically, the initialisation of my AJAX tabs was causing the google map to lose its positional information - so to reset it I needed to call map.checkResize() - which seemed to cure the problem :)

Friday, August 14, 2009

Creating indicies on views

Because runsaturday maintains two user databases - one for yaf and one for dnn - I wanted to create a lookup table from one set of userids to the other.

And the easiest way of doing this automatically was a view with an index.

But to create the index on the view - I had to remember the SchemaBinding trick - see for more information about schema bound views.

Wednesday, August 12, 2009

The Joel Test

I've not really seen this before - but just been sent it within the UK MSDN Flash today - - interesting stuff:

The Joel Test

  1. Do you use source control?
  2. Can you make a build in one step?
  3. Do you make daily builds?
  4. Do you have a bug database?
  5. Do you fix bugs before writing new code?
  6. Do you have an up-to-date schedule?
  7. Do you have a spec?
  8. Do programmers have quiet working conditions?
  9. Do you use the best tools money can buy?
  10. Do you have testers?
  11. Do new candidates write code during their interview?
  12. Do you do hallway usability testing?

And once you have answered those questions, share with the rest of us how you scored. 

I think I score a 8 or 9... I'll let you guess which ones I don't do... and which one I half kind of do.

Wednesday, July 29, 2009

"The process cannot access the file because it is being used by another process"

You receive a "The process cannot access the file because it is being used by another process" error message when you try to start a Web site in the Internet Information Services MMC snap-in


The solution in my case was:
- stop Skype - it was using port 80....

Monday, June 15, 2009

ModuleLoadException - RSS/News with DNN5

Saw this problem with the RSS/News feed module under DNN5 - using ASP.Net 3.5 SP1.

Eventuallly... after several hours... tracked it down to the file RssModule.ascx which hard codes the System.Web.Extensions version number:

<%@ Register assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI" tagprefix="asp" %>

Replaced this with

<%@ Register assembly="System.Web.Extensions" namespace="System.Web.UI" tagprefix="asp" %>

And life was OK again (phew!)

Have reported to DNN for fixing.

Error: News Feeds (RSS) is currently unavailable.
DotNetNuke.Services.Exceptions.ModuleLoadException: Could not load file or assembly 'System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified. ---> System.Web.HttpParseException: Could not load file or assembly 'System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified. ---> System.Web.HttpParseException: Could not load file or assembly 'System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified. ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified. File name: 'System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) at System.Reflection.Assembly.Load(String assemblyString) at System.Web.Configuration.CompilationSection.LoadAssembly(String assemblyName, Boolean throwOnFail) at System.Web.UI.TemplateParser.LoadAssembly(String assemblyName, Boolean throwOnFail) at System.Web.UI.TemplateParser.AddAssemblyDependency(String assemblyName, Boolean addDependentAssemblies) at System.Web.UI.MainTagNameToTypeMapper.ProcessTagNamespaceRegistrationCore(TagNamespaceRegisterEntry nsRegisterEntry) at System.Web.UI.MainTagNameToTypeMapper.ProcessTagNamespaceRegistration(TagNamespaceRegisterEntry nsRegisterEntry) at System.Web.UI.BaseTemplateParser.ProcessDirective(String directiveName, IDictionary directive) at System.Web.UI.TemplateControlParser.ProcessDirective(String directiveName, IDictionary directive) at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding) WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure logging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog]. --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.ProcessException(Exception ex) at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding) at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding) --- End of inner exception stack trace --- at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding) at System.Web.UI.TemplateParser.ParseReader(StreamReader reader, VirtualPath virtualPath) at System.Web.UI.TemplateParser.ParseFile(String physicalPath, VirtualPath virtualPath) at System.Web.UI.TemplateParser.ParseInternal() at System.Web.UI.TemplateParser.Parse() at System.Web.UI.TemplateParser.Parse(ICollection referencedAssemblies, VirtualPath virtualPath) at System.Web.Compilation.BaseTemplateBuildProvider.get_CodeCompilerType() at System.Web.Compilation.BuildProvider.GetCompilerTypeFromBuildProvider(BuildProvider buildProvider) at System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders() at System.Web.Compilation.BuildProvidersCompiler.PerformBuild() at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.Compilation.BuildManager.GetVPathBuildResult(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile) at System.Web.UI.TemplateControl.LoadControl(VirtualPath virtualPath) at System.Web.UI.TemplateControl.LoadControl(String virtualPath) at DotNetNuke.UI.ControlUtilites.LoadControl[T](TemplateControl containerControl, String ControlSrc) at DotNetNuke.UI.Modules.ModuleHost.LoadModuleControl() --- End of inner exception stack trace ---

Wednesday, June 10, 2009

Problems precompiling site - BC30560: 'ScriptServiceAttribute' is ambiguous

Installed a brand new DNN 5.0.1 installation.

Upgraded web.config to 3.5 Framework version.

Added my own modules.

Tried to precompilte....

But sadly things went wrong... 'ScriptServiceAttribute' is ambiguous

Spent a long time looking inside web.config for the problem.... couldn't see it.

Eventually discovered that something (not sure what - was it in DNN?) had installed an old version of system.web.extensions.dll into my bin directory....


(at least next time I'll check there first)

Tuesday, June 09, 2009

Windows 2008 server - connecting to GoGrid storage

Wish I'd blogged this first time - as i'd have found it more quickly then:

First setup the routing:

Then setup the SAMBA link: (see the bottom of this page for Windows instructions)

Wednesday, May 27, 2009

Got the plugin working on Firefox... now Chrome

The plugin worked on Firefox!

But under Chrome it kept crashing....

The problems seem to be down to:
1. A whole load of test and demo code in CPlugin::CPlugin - in plugin.cpp - couldn't be bothered to find out which bit of it caused the crash - it was all just demo code from the sample - so I cut it all out!
2. Problems with the way the sample code used malloc and strdup to allocate memory... these need to be replaced with NPN_MemAlloc for Chrome (and really for Firefox too!)

This page seems to help a bit...

But really it is hard work to debug!

Monday, May 25, 2009

Starting out on Firefox plugins

I've been working on a new Firefox plugin.

stage one... was to get the code I wanted to working as an ActiveX control inside Internet Explorer.

stage two... was to then start on getting the mozilla code working - this guide for Visual Studio building is a little out of date - but still seemed to basically work:

The main things that didn't work were:
- problems with changes in function names
- problems with int32_t types which seem to have been removed!

Thursday, May 21, 2009

Eeeeek - back in C++ land

Spent a long time today trying to get a project to link :)

Eventually worked it out - but it took some decoding of name mangling - - it eventually became "obvious" that the library I was linking against was built using VC++ 6.0 - before w_char as a type was introduced - so one of my names didn't match one of the mangled names...

I'm really finding it hard to work in C++ after 3 years of mostly C# though!

Monday, May 18, 2009

If you encounter ASP Validators not working in Chrome

This solution seemed to work rather well for me:

<script type="text/javascript">
    evt = ""; // Defeat the Chrome bug

Monday, May 11, 2009

Making an AJAX TabPanel really invisible

If you want to make a TabPanel invisible using the ASP.NET AJAX
TOOLKIT then it seems you have to make the header text invisible too.
I did this using:

if (!viewedPreferences.ShowHealthInProfile)
TabPanelHealth.Visible = viewedPreferences.ShowHealthInProfile;
TabPanelHealth.HeaderText = string.Empty;

Monday, March 23, 2009

ASP.NET textbox multiline maxlength

Very useful and simple javascript if you want to protect a multiline text box from enterting too many characters!

function CheckCount(text,length)




      var maxlength = new Number(length); // Change number to your max length.


if(text.value.length > maxlength){


                text.value = text.value.substring(0,maxlength);


                alert(" Only " + maxlength + " characters allowed");



<asp:TextBox ID="textBox" onKeyUp="javascript:Count(this,100);" onChange="javascript:Count(this,100);"  TextMode=MultiLine Columns="5" Rows="5" runat=server>


Or something like that...

Some useful pages for OpenSocial

Just starting to look at this now...

Here's some useful OpenSocial pages I've found:

This reply is very useful with links and ideas:

Here's the Ning hello world application:

The iGoogle page is very good - and I use their sandbox quite a lot! - - sandbox at

(I also find it quite funny that Google has a "legacy" gadget section already!

Here's the developer's guide

An example gadget (not quite opensocial) on CodeProject -

MySpace also has opensocial capabilities - (I never use MySpace - but maybe I should take a look one day)

The  site is very useful - e.g. here's a tutorial - and here's a list of containers -

Another interesting tutorial - (plus also see their Gadget tutorial -

Not sure about this link - it's about xml2json - but I think there may be better ways available now -

Thursday, March 19, 2009

Changing YetAnotherForum to display time as "x minutes ago"

This really demonstrates the beauty of open source!

I've got a lot of international visitors to - so I wanted to avoid time zone specific times (yes - I know YAF does let each user customise the time zone, but that doesn't really help when I get so many guests through)

So ... I decided to adopt the facebook/twitter approach - to listing times like "23 seconds ago" and "in the last week".

It was remarkable easy to change. Here's the main new code:

        /// <summary>

        /// Formats a datetime value into "friendly terms" - let's hope this works!

        /// the date is yesterday or today -- in which case it says that.

        /// </summary>

        /// <param name="o">The datetime to be formatted</param>

        /// <returns>Formatted string of DateTime object</returns>

        public string FormatDateTimeTopic(object o)


            //string strDateFormat;

            DateTime dt = Convert.ToDateTime(o) +TimeOffset;

            DateTime nt = DateTime.Now+TimeOffset;


            TimeSpan diff = nt - dt;

            double totalSeconds = diff.TotalSeconds;

            double totalMinutes = diff.TotalMinutes;

            double totalHours = diff.TotalHours;

            double totalDays = diff.TotalDays;




                if (totalSeconds < 15.0)


                    return GetText("MomentsAgo");


                if (totalSeconds < 100.0)


                    return string.Format(GetText("SecondsAgo"), totalSeconds);


                if (totalMinutes < 100.0)


                    return string.Format(GetText("MinutesAgo"), totalMinutes);


                else if (totalHours < 10.0)


                    return string.Format(GetText("HoursAgo"), totalHours);


                else if (totalDays < 1.0)


                    return GetText("InTheLastDay");


                else if (totalDays < 2.0)


                    return string.Format(GetText("ADayAgo"), totalDays);


                else if (totalDays < 30.0)


                    return string.Format(GetText("DaysAgo"), totalDays);




                    return dt.Date.ToString("dd MMM yy");



            catch (Exception)


                return dt.ToString("f");




Old code was:

            /// <summary>

            /// Formats a datatime value into 07.03.2003 00:00:00 except if

            /// the date is yesterday or today -- in which case it says that.

            /// </summary>

            /// <param name="o">The datetime to be formatted</param>

            /// <returns>Formatted string of DateTime object</returns>

            public string FormatDateTimeTopicOld( object o )


                  string strDateFormat;

                  DateTime dt = Convert.ToDateTime( o ) + TimeOffset;

                  DateTime nt = DateTime.Now + TimeOffset;




                        if ( dt.Date == nt.Date )


                              // today

                              strDateFormat = String.Format( GetText( "TodayAt" ), dt );


                        else if ( dt.Date == nt.AddDays( -1 ).Date )


                              // yesterday

                              strDateFormat = String.Format( GetText( "YesterdayAt" ), dt );


                        else if ( BoardSettings.DateFormatFromLanguage )


                              strDateFormat = dt.ToString( GetText( "FORMAT_DATE_TIME_SHORT" ) );




                              strDateFormat = String.Format( "{0:f}", dt );


                        return strDateFormat;


                  catch ( Exception )


                        return dt.ToString( "f" );




Connecting to SQL Server Express remotely

I'm beginning to become more of a power user....

The section below is copied from (just copying it in case the original disappears)

Although by the time I become a proper power user I'll hopefully be on the full monty - not the express!

Here's the instructions:

Here's a quick summary of the actions you need to take. The first three actions have a separate page which provides more details and some screen shots of the procedure.

  1. [Link] Enable the TCP/IP protocol using the Surface Area Configuration Utility
  2. [Link] Make sure the TCP/IP protocol is enabled in the SQL Server Configuration Utility
  3. [Link] Make sure the SQL Server browser is started. Note this step is optional. It is possible to set the SQL Server instance to use a fixed IP address - but this is non-standard for named instances. See sqlexpress's WebLog for details.
  4. Make sure SQL Server and SQL Server Browser are exempted by the firewall on the server machine. This is done by putting sqlservr.exe and sqlbrowser.exe as an exception in the windows firewall. Chris D. sent in a note which might help.
  5. Note: In order to get things to work. You might need to completely reboot the server machine after making the changes. There have been reports (thanks P.C.) that starting and stopping the SQL Server and Browser software is not enough.

Monday, March 16, 2009

Essential reading if you are trying to run DNN5 with a proper SQL Server Express Connection String...

This blog post has just saved me lots of horrible experimentation

Basically I've been running using "File" access - and now it's definitely time to move up to "proper" access. For a start it will make my backup process 100 times easier :)

Post is reproduced here - just so it can go missing in any reorg at DNN:

Recently I rebuilt my laptop and decided to only install SQL Express and not the full SQL Server 2005.  The issue I can across occurs when you attach to the DNN mdb file within SQL Server Management Studio.  Once you have done that the connection string does now work and you DNN site cannot connect to the database. And no matter what you do you cannot correct it even by detaching it, restart SQL Express, resetting IIS, etc.  I finally had to scrap the database and do it all again.  Below is the way to setup DNN and SQL Express if you want to also access the database from within SQL Server Management Studio.

1) Rename the Database.mdb to another name.  (This is optional).

2) Open SQL Server Management Studio and do the following 
  • Attach the database 
  1. Right click on the database folder and choose attach.
  2. Click Add button and point to the database you want to attach to.
  3. Click on the "Attach As" column and give it a more friendly name.  For this blog purpose we will change it to DotNetNuke_ModDev
  4. In the lower screen delete the line that references the ".ldf" file.  This will be created and you will get an error that it cannot be found if you do not delete it.
  5. Click on the "Current File Path" for the ".mdf" file and update it so it points to the location of the DNN database you are attaching to.
  6. Click Okay and the database should be attached correctly.
  • Set up permissions
    • Adding Login
      1. Click on the security\logins folder.
      2. If the ASPNet user exist you can skip this section.
      3. Right click login folder and choose "New Login"
      4. Click the "Search" button, then the "Advance" button, and then the "Find Now".  This will bring up a list of user on the computer and select the ASPNet account.
      5. Make sure Windows authentication is checked and click "OK" to add user.
    •  Adding Database User
      1. Click on "Databases\Security\Users folder.
      2. If the ASP.Net user exist you can skip this section
      3. Right click the user folder and choose "New User"
      4. Click on the "..." button next to the Login Name, then click on the "Browse" button.
      5. Check the ASPNet user and click "OK" button.  Click the OK button on the Select Login screen and this will add the user.
      6. Under database role membership check one of the following combinations.  Option #2 is more secure.  Click "OK" button when done.
        • Permission Options #1
          • dbowner
        • Permission Options #2
          • db_datareader
          • db_datewriter
          • db_ddladmin
          • db_securityadmin
    • Setting Database Permissions (Only needed it Option #2 is chosen above)
      1. Right click on the database you attached to and choose "Properties"
      2. Click on "Permissions" under select a page (upper-left of screen).
      3. Under Explicit permission for {Database Name}, make sure that the Grant box is checked for Execute.
3) Update the connection strings in the DNN web.config file.  Do not forget to use the same connection string in the <ConnectionString> and <AppSettings> section.

Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|Database.mdf;


Data Source=.\SQLExpress;Integrated Security=True;User Instance=False;Database=DotNetNuke_ModDev;

4) Access the DNN web site to run the installation process.

You should now have a working DNN site and a SQL Express database that you can access/manipulate using SQL Server Management Studio and still be able to access it from the web site as well.

Validation of viewstate MAC failed / The state information is invalid for this page and might be corrupted

I'm hitting some of these problems on runsaturday at the moment.

These definitely aren't being caused by machinekey errors - this is occurring on a single PC.

Some of these might be occurring due to some specific DotNetNuke behaviour - especially when the page makeup changes during a postback.

However, in one particular case - I have one specific Mac user who (regardless of whether he uses Firefox or Safari) just occasionally seems to randomly hit one of these problems).

This has me quite stumped.... but I'm still looking :)

Here's one discussion that seems to be particularly relevant -

Wednesday, March 04, 2009

Still trying to understand IIS7....

This excellent post has at least solved one of my queries - I simply could not understand why IIS7 didn't let me select .NET 3.5 - the answer is in the runtime...

Tuesday, March 03, 2009

Problems using ThreeSharp with bucket names containing DOTs

I'm trying to set up a bucket name at the moment (for public access) and keep hitting:

The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel

One solution seems to be not to include "config.Format = CallingFormat.SUBDOMAIN;" - but this obviously won't help people with European buckets.

Sunday, March 01, 2009

Azure downtime report

Using host-tracker to check my Azure sites.

Here are the stats from Feb - I think all downtime must be from Azure itself - I haven't taken the site down at any point.

I can also get a response time report if anyone is interested


   Total uptime:99.71% Downtime:2 hour(s) 13 min(s)
       Monthly uptime:99.75% Downtime:1 hour(s) 39 min(s)
           Day 2009-02-28 Uptime:100.00%
           Day 2009-02-27 Uptime:100.00%
           Day 2009-02-26 Uptime:100.00%
           Day 2009-02-25 Uptime:100.00%
           Day 2009-02-24 Uptime:96.00% Downtime:57 min(s) 37 sec(s)
           Day 2009-02-23 Uptime:100.00%
           Day 2009-02-22 Uptime:100.00%
           Day 2009-02-21 Uptime:100.00%
           Day 2009-02-20 Uptime:97.12% Downtime:41 min(s) 30 sec(s)
           Day 2009-02-19 Uptime:99.95% Downtime:41 sec(s)
           Day 2009-02-18 Uptime:100.00%
           Day 2009-02-17 Uptime:100.00%
           Day 2009-02-16 Uptime:100.00%
           Day 2009-02-15 Uptime:100.00%
           Day 2009-02-14 Uptime:100.00%
           Day 2009-02-13 Uptime:100.00%
           Day 2009-02-12 Uptime:100.00%
           Day 2009-02-11 Uptime:100.00%
           Day 2009-02-10 Uptime:100.00%
           Day 2009-02-09 Uptime:100.00%
           Day 2009-02-08 Uptime:100.00%
           Day 2009-02-07 Uptime:100.00%
           Day 2009-02-06 Uptime:100.00%
           Day 2009-02-05 Uptime:100.00%
           Day 2009-02-04 Uptime:100.00%
           Day 2009-02-03 Uptime:100.00%
           Day 2009-02-02 Uptime:100.00%
           Day 2009-02-01 Uptime:100.00%

   Total uptime:98.83% Downtime:8 hour(s) 54 min(s)
       Monthly uptime:99.86% Downtime:55 min(s) 44 sec(s)
           Day 2009-02-28 Uptime:100.00%
           Day 2009-02-27 Uptime:100.00%
           Day 2009-02-26 Uptime:100.00%
           Day 2009-02-25 Uptime:100.00%
           Day 2009-02-24 Uptime:98.23% Downtime:25 min(s) 29 sec(s)
           Day 2009-02-23 Uptime:100.00%
           Day 2009-02-22 Uptime:100.00%
           Day 2009-02-21 Uptime:100.00%
           Day 2009-02-20 Uptime:98.08% Downtime:27 min(s) 43 sec(s)
           Day 2009-02-19 Uptime:99.82% Downtime:2 min(s) 32 sec(s)
           Day 2009-02-18 Uptime:100.00%
           Day 2009-02-17 Uptime:100.00%
           Day 2009-02-16 Uptime:100.00%
           Day 2009-02-15 Uptime:100.00%
           Day 2009-02-14 Uptime:100.00%
           Day 2009-02-13 Uptime:100.00%
           Day 2009-02-12 Uptime:100.00%
           Day 2009-02-11 Uptime:100.00%
           Day 2009-02-10 Uptime:100.00%
           Day 2009-02-09 Uptime:100.00%
           Day 2009-02-08 Uptime:100.00%
           Day 2009-02-07 Uptime:100.00%
           Day 2009-02-06 Uptime:100.00%
           Day 2009-02-05 Uptime:100.00%
           Day 2009-02-04 Uptime:100.00%
           Day 2009-02-03 Uptime:100.00%
           Day 2009-02-02 Uptime:100.00%
           Day 2009-02-01 Uptime:100.00%

Friday, February 27, 2009

DotNetNuke, Roles and Invalid value for 'encrypted ticket parameter'

On I was using DNN's roles for friends... then one day I couldn't log on.

The reason? I had too many friends :)

Basically the problem was that DNN was inserting a very long string into a cookie....

To work around this I'll need to either change my code to not use the DNN roles structure or insert an HTTPModule to tweak their Roles behaviour.

Here's the DNN thread:

Tuesday, February 24, 2009

I was sure I'd already blogged this - colors (colours) darker and lighter

From (and other sources) you can use ControlPaint to help with lightening and darkening colours.

Integrating Twitter

I've been playing with quite a lot over the last week or two.

On the send side, I used the tweetsharp project to send tweets - if you're a user then you'll have seen this - if not, then you can't see it! -

On the browse side, I used twitter.js to show people's tweets on their runsaturday profile - see for an example -

Both libraries come recommended

Sunday, February 22, 2009

Starting to think about internationalisation

Someone's emailed me from Martinique.

Yes, I had to lookup were that was! (It is on Google Maps but not on all of them - e.g. not on Google static maps!)

Anyways, it's got me thinking about internationlisation (i18n) for runsaturday. I think it should be possible to do this... I might have a go soon...

Need to go back over my code first and find out which modules have strings naughtily hardcoded... but then I think it should be possible to translate the existing site quite quickly - maybe in less than a week....

It must be done! But then so must a lot of other things....


Saturday, February 21, 2009

Preprocessor directives must appear as the first non-whitespace character on a line

Dodgy error from the compiler....

"Preprocessor directives must appear as the first non-whitespace character on a line"

What this actually meant was I'd tried to use two DataBinding expressions inside the same property -

                <asp:Label ID="UserName" runat="server" Text='<%# Eval("UserName") %><%# Eval("TeamMemberNameText") %>'></asp:Label>

To solve it I just pulled it down to:

                <asp:Label ID="UserName" runat="server" Text='<%# Eval("UserAndTeamMemberNameText") %>'></asp:Label>

Wednesday, February 18, 2009

Replacing the far too secure random password generation in DotNetNuke

When using my facebook connect authentication plugin (on, the password generated by DNN is far, far too secure for most users.

It looks like ASH783934_w3w-r - i.e. not very easy to remember.

I wanted to replace it - so used a class like....

    public class SlodgeDNNMembershipProvider : DotNetNuke.Security.Membership.AspNetMembershipProvider


        static List<string> PasswordBase = new List<string>()




            ... lots of other simple keywords,





        public override string GeneratePassword(int length)


            // length ignored - hope this does not hurt the SQL layer!

            return GeneratePassword();



        public override string GeneratePassword()


            Random r = new Random();

            int index = r.Next(PasswordBase.Count);

            if (index >= PasswordBase.Count) // according to the intellisense help this should not happen

                index = PasswordBase.Count - 1;


            int number = r.Next(100);

            return string.Format("{0}{1:00}", PasswordBase[index], number);



And then inserted this into the web.config layer using:

            <members defaultProvider="AspNetMembershipProvider">



                        <add name="AspNetMembershipProvider" type="SlodgeDNNMembershipProvider.SlodgeDNNMembershipProvider, SlodgeDNNMembershipProvider" providerPath="~\Providers\MembershipProviders\AspNetMembershipProvider\"/>



Seemed to work first time - which is always suspicious!