Tim Huffam

Dotting the I and crossing the T of I.T.

  Home  |   Contact  |   Syndication    |   Login
  127 Posts | 0 Stories | 787 Comments | 677 Trackbacks

News

Archives

Post Categories

Interesting Blogs/Links

Thursday, October 09, 2008 #

This will actually remove the your workspaces - unlike the VS/TFS Source Control Explorer which simply does not display them - duh!
 
From the VS command prompt:
  tf workspaces /remove:*
 

Friday, September 26, 2008 #

If a user, using Firefox 3, signs out of a web site and does not close the browser, anyone else using that browser subsequently can view the content of pages loaded by the previous user (eg in an internet cafe, or any place where workstations are shared eg universities) - exposing private/confidential data.

This only affects HTTP post requests (not gets) and only Firefox version 3 - earlier versions (1.5, 2 etc), and IE, are not affected.
 
The main points are:
  • This is definately a bug:  a violation of RFC 2616, section 14.9 that states "The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain".
  • Some companies who deem this a significant hole in their security have chosen to block requests from Firefox 3 (eg they deem it their responsibility to secure their customers private and confidential data to the best of their ability).
  • This bug has been registered with the Mozilla dev team, but currently (as of 26 Sept 2008) has a status of unconfirmed.
Related links:

Tim


Tuesday, September 09, 2008 #

The following error occured when 2 requests hit an ASP.NET (2.0) web app (using SQL Server 2005) at the same time:

The connection was not closed. The connection's current state is open

Normally this only occurs if you have a connection that is not being closed.  However in our case all connections where being closed using a try-finally block (personally I prefer using a using block).

This error only occured when the 2 request were initiated from different machines.

It turns out that the error occured because the same username was being used  for all requests (we were not interested in the username  in the app - and simply validated the request through a token and set the username to the same static string for all requests).  As soon as we made the username unique (by appending a guid to it) the error ceased to occur.

This indicates that ADO.NET uses the username as part of it's connection pooling management. 

HTH

Tim


For some time I've been wondering if there's a better way to program business logic.  Years ago I used to write COBOL, then moved onto a 4GL, bla bla bla... and today I find myself well entrenched in OO with Microsoft's .Net.  Development times don't seem to be much better these days - and the complexity of things seems to have mushroomed. 

We went from barely-a-3GL to 4GL back to 3GL plus an explosion of things you need to consider.  We started with procedural code then moved to OO and seem to have got stuck there.  But somehow I think we need to revise our use of OO.  Business logic is predominantly procedural code - even if written in OO; it starts, follows a process, performing stuff until finished eg Customer.UpdateCreditLimit()

OO is really good for modelling things - as per the classic OO examples of a bicycle or car.  And thus they model business things quite well too - like an Invoice or a Customer. 

However, I've found that the more object oriented the code gets - the less productive, maintainable and flexible it becomes.  Not saying leave OO - far from it - it's brilliant.  It's just that we need to learn when to say 'when'.   The use of patterns has helped a huge amount - but these can also caused similar problems - when being applied where they aren't really needed - resulting in overly complex software (read: inflexible and unmaintainable and unproductive).  It's a fine line - and it's not easy to get the balance.

A major break through in this area is LINQ.  This has meant we have less clutter in our apps catering for ORM (brilliant).  This has resulted in code very similar to the old 4GL days (essentially 4GLs were just SQL based code anyway) - where all you care/code about is the business logic - caring not a jot about how or where a Customer or Order got created - and in this age of SOA - that becomes more important (as a Customer could come from many different sources - local RDBMS, company ERP, external CRM etc).  I guess you could say LINQ allows you to focus your code to be more domain specific (not saying it's a DSL).

I have been playing with workflows for donkeys of years and found that although the individual workflow systems themselves can range from very simple to incredibly complex - the individual tasks they perform need not be.   This had lead me to start thinking about applying this principle to code design at a reasonably low level....  what if we developed tasks as objects.  Each task has just one job (I've heard some people say this is how objects 'should' be coded anyway).  It has properties that can be get/set.  Keeping things dead simple, eg:

public class AdderTask
{
   
public int Addend1 { get; set
; }
   
public int Addend2 { get; set
; }
   
public int Result { get; set
; }
   
public AdderTask(int addend1, int
addend2)
    {
       
Addend1 = addend1;
       
Addend2 = addend2;
    }
   
public AdderTask
Execute()
   
{
        Result = Addend1 + Addend2;
       
return this
;
   
}
}

To run this you'd simply do this:

int result = new AdderTask(1, 2).Execute().Result;

Exposing the task's properties means you can build up get and set statements - and because the Execute method returns the task object itself you can easily use it in a single line as if it was a method on it's own - or retrieve it's property values after the Execute (these tasks would easily be adapted to work within a workflow system).

This style lends itself to expanding; rather like building blocks, you can build large workflows out of these task oriented blocks.  The workflows themselves coded just like these tasks - whereby all the business logic resides within the Execute() method.

Adding LINQ to the mix takes this to the next level - allowing you to build software that is simple to develop and understand.

I've been building a sizable system using this technique and I'm finding that I'm converting code developed using standard OO practices over to this methodology as it makes code more easily reused - but most importantly: easier to read and maintain.

In summary:

  • All input and output parameters should be implemented as properties (getter and setter accessors).
  • Provide a constructor that accepts all required parameters. A default constructor (with no parameters) is optional (I've found I never need these - but if you were to use these tasks in a workflow system they may need this).
  • Provide an Execute() method that takes no parameters and returns the object instance eg return this;
  • The object should clean up after itself. 

Other notes:

  • Originally I created a similar type of class for workflows - but I found that these ended up being no different in concept to tasks.  Likewise I've found that some tasks needed to call other tasks - so I've ended up just implementing everything as tasks.  On reflection this is actually quite valid - because, as I found when building large orchestrations using Biztalk, workflows become atomic tasks themselves when used within the context of a large orchestration (which may run many workflows and external tasks) - and the orchestration, from a highlevel could also be considered an atomic task.
  • I've found using System.Transactions.TransactionScope great for scoping transactions around many tasks when creating a macro task that runs many sub tasks.

Suggestions/comments very welcome - I'd like others to expand or comment on this.

Tim


Saturday, September 06, 2008 #

A couple of notes regarding absolute positioning in FF and IE...

Specifying position values:

  • IE allows you to omit the unit of measurement for Left and Top.  It assumes pixels eg:
        obj.style.Left = 10;
  • However FF requires that you specify the unit of measurement eg:
        obj.style.Left = "10px";

Using other elements parents to calculate your object's position:

The scenario might be you have a div that you want to position over or by another object - but that object has no position values.  In this case I use parent object values.

  • Don't use the IE specific property parentElement (this is not supported in other browsers) eg:
        obj.style.Left = otherObj.parentElement.offsetLeft + 10; 
    note in this example (that works in IE only) there is no unit of measurement.
  • Instead use the parentNode property (this works for both IE and FF) eg:
        obj.style.left = (otherObj.parentNode.offsetLeft + 10) + "px";

HTH
Tim


Wednesday, August 27, 2008 #

Sometimes Visual Studio 2008 (Team System Developer Edition - with Team Explorer and TFS Power Tools) crashes (disappearing completely) when running unit tests.

I have not yet tried SP1 for VS2008 - will hopefully try this in the next week or two.

Not really sure what causes this - but have noticed that the following error is written to the windows event log prior to the crash (not at the same time).

Event Type: Error
Event Source: VSPERF
Event Category: None
Event ID: 1406
Date:  22/08/2008
Time:  16:27:18
User:  N/A
Computer: MYPC
Description:
There was an error connecting to the Logger Engine while registering C:\Dev\DEV\Release1\Source\MyWebProject\bin\MyWebProject.dll for coverage.

Initially I thought it was a particular test or peice of target code that caused it, but found that the crash occured at seemingly random moments ie I tried running all tests and it would crash at test number 259 (out of 264), then tried running the first 100 tests and it crashed - then tried the last 20 tests and it crashed-  even tried running 1 test and it crashed.  This was the worst case of this problem - over the past few weeks it (VS crashing/disappearing) would only happen every now and then.

The only work around I've found is to replace or remove the workspace and start again...

  1. If you have pending changes, shelve them first.
  2. Using Source Control Explorer, remove the workspace.
  3. Close the solution in VS.
  4. Within a VS command prompt run the following command to remove all workspaces (if you have many workspaces and only want to remove the one workspace then specify it's name instead of the asterisk used below):
        tf workspaces /remove:*
  5. Use the Source Control Explorer to recreate a new workspace. 
    Note: if you have scripts/macros that reference your original workspace source dir, then it would pay to use the same dir - if you do,  make sure you delete the contents of this dir before reassigning it to the new workspace.

HTH
Tim


Monday, August 18, 2008 #

When trying to debug javascript using Visual Studio 2008 there a couple of things you need to do first - otherwise it (debugging) will not work and you'll get the following error when you hover over breakpoint in your javascript:

The breakpoint will not currently be hit. No symbols have been loaded for this document.

Note that this is only for debugging using IE (6) - not sure about other browsers/versions.

  1. Within IE go into Tools - Internet Options - Advanced tab and make sure the 'Disable Script Debugging' is unchecked.
  2. Make sure you have a breakpoint in your javascript.
  3. Start debugging your web app in VS.
  4. Within VS select menu item Debug - 'Attach to Process...'
  5. On the Attach to Process dialog, select the row which has explorer.exe for your app (the Title column will have you page title on it), then click Attach.

That's it - when your breakpoint is reached the VS debugger will be triggered.

HTH
Tim


Thursday, July 24, 2008 #

For those of you wanting to know just what is being sent (posted) back from the client (browser) to the server (ASP.NET) - when a postback occurs - use the following lines in your C# ASP.NET program:

 

string msg = "";
for (int
i = 0; i < Request.Form.AllKeys.Length; i++)
{
  msg += i.ToString() +
" " + Request.Form.GetKey(i) + ": " + Request.Form[Request.Form.GetKey(i)] + "\r\n"
;
}
System.Diagnostics.
Debug.WriteLine(msg);

Either look at the output window or put a break-point on the last line so you can use the debugger to view the variables values at runtime.

Note that this only the information within the HTTP POST payload.  There are also things like the HTTP headers, cookies etc (all of which you can query in a similar fashion - all within the Page.Request object).

Normally I'd use a tool like Fiddler for this type of interogation - but sometimes it's just as quick and easy to do it in the code like this.

HTH

Tim


Wednesday, July 23, 2008 #

Fresh chocolate chip cookies and fresh coffee over garden variety cookies and instant coffee

That is, while there is value in the items on the right, we value items on the left more.

The unspoken rule is that non-team members attending team meetings must come bearing the fore mentioned items


Friday, July 11, 2008 #

For those of you who don't have access to IE or FF dev toolbars - this is how we used to do client side runtime debugging...

Drop the following code into your web page (preferrably at the bottom):

<script>
function
log(text){
  document.getElementById("logArea"
).value = text;
}
function
dump(){
  log(document.body.innerHTML);
}
function logProps(obj){
 
var msg = "";
  for(var i=0;i<obj.attributes.length;i++)
  {
    msg+=obj.attributes[i].nodeName + ": " + obj.attributes[i].nodeValue + "\r\n";
  }
  log(msg);
}

</script>
<
input ondblclick="eval(this.value)" /><br
/>
<
textarea id="logArea" cols="80" rows="20"></textarea>

This should be self explanatory - the html controls provide a place to enter and run javascript (eg to query the DOM at runtime) and somewhere to dump the data.  And the javascript provides some helper functions - for dumping data and for querying all the properties of an object.

The following is a IE specific version of the for loop which may show a few other properties:
  for(x in obj)
  {
    msg+=x + ": " + obj[x] + "\r\n";
  }

HTH
Tim


Wednesday, July 09, 2008 #

For some reason some controls/tags within ASP.NET do not always get rendered/passed to the client. 

This has happened to me on a number of occasions.  It seems limited to <style> and <script> tags - but happens for both raw HTML (within the aspx designer) and dynamically created tags (eg using new HtmlGenericControl("style")...).

This is happening to controls/tags within AJAX updatepanels within, webforms and usercontrols.

Sometimes I can work around this by simply placing these controls/tags some where else within the page structure.  But the most consistent way to get around this issue is to place a non-blanking space before the tag eg:

&nbsp;<style>...

Another half-baked solution hit's the road ;-)

Update:

After some investigation, I have found a not-so-half-baked solution - for getting javascript loaded and run on a page during an AJAX postback... 

The solution is to not try and add a script tag by adding it to a control within the page - but rather use the ASP.NET AJAX ScriptManager class's RegisterStartupScript() method.  There are two overloads for this, one loads/registers the script and runs it just once (initial page load) and the other on each asynchronous postback (the latter suited my needs).

HTH
Tim


The following javascript error occurs when trying to use the Telerik controls and you haven't updated your ASP.NET (2.0) web.config file correctly.

Error: 'Telerik' is undefined

To fix make sure the following lines are within the <system.web> section of your web.config file:

<httpHandlers>
  <
add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />
  <
add path="ChartImage.axd" verb="*" type="Telerik.Web.UI.ChartHttpHandler, Telerik.Web.UI, Version=2008.1.515.20, Culture=neutral, PublicKeyToken=121fae78165ba3d4" validate="false" />
  <
add path="Telerik.Web.UI.WebResource.axd" verb="*" type="Telerik.Web.UI.WebResource, Telerik.Web.UI, Version=2008.1.515.20, Culture=neutral, PublicKeyToken=121fae78165ba3d4" validate="false" />
</
httpHandlers>

In my case I was missing the ScriptResource.axd line.   Also, you only need the ChartImage.axd line if you're using the chart control.

HTH
Tim


Friday, July 04, 2008 #

With a clean install of Scuttle I found that both the import bookmarks pages (importNetscape.php and import.php) do not work - instead the both display the source of the PHP files.

This is caused by both files not having the correct php declaration at the beginning of the file eg -both of these files first line was:

<?

However they should have been:

<?php

So just simply update these files.

HTH
Tim

 


I got the following error on a fresh install of Scuttle (0.7.2) on a newly created Windows Server 2003 with PHP (5.2.6),  MySQL5.0.51b) and IIS 6:

Warning: setlocale() [function.setlocale]: Passing locale category name as string is deprecated. Use the LC_* -constants instead in C:\Inetpub\Scuttle\includes\php-gettext\gettext.inc on line 131

Warning: setlocale() [function.setlocale]: Invalid locale category name LC_MESSAGES, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, or LC_TIME in C:\Inetpub\Scuttle\includes\php-gettext\gettext.inc on line 131

After googling for a while I found this simple solution (here: http://www.hermann-uwe.de/blog/server-client-bookmarks-a-la-del-icio-us#comment-52097 posted by CharlesW):
Add the line: if (!defined('LC_MESSAGES')) define('LC_MESSAGES', 5);
to the top of functions.inc.php.


Thanks a million CharlesW!!!


Wednesday, July 02, 2008 #

It seems every time I try to install PHP and MySQL something doesn't work - usually there's either a file missing from the PHP distro or something in the install notes is missing or incorrect.  This time it was both.

I first tried the PHP msi install - first mistake.  As it does not include the MySQL extensions - neither does the 5.2.6 PECL zip file (I mistakenly thought this would include all the extensions).  So if you've installed PHP using the MSI installer - uninstall it (via Control Panel - Add/Remove Programs).  Also - you may need to manually remove any remants of this PHP installation manually - I had to manually delete the php directory.

Now with a clean slate do the following:

  1. Download the PHP zip package from here.
  2. Extract the zip - in my case into D:\php-5.2.6-Win32
  3. Copy php.ini-recommended and rename it to php.ini (within this same dir).
  4. Edit php.ini and make the following changes:
    1. Set the extension dir eg:
      extension_dir = "D:\php-5.2.6-Win32\ext"
    2. Uncomment the extension setting for mysql eg remove the ';' from the beginning of the line:
      extension=php_mysql.dll
  5. Within IIS admin tool:
    1. Within Application Configuration (within 'Home Directory' of a site) add the php extension - mapping 'php' to php5isapi.dll (eg D:\php-5.2.6-Win32\php5isapi.dll).
    2. Within Web Service Extensions add one for php5isapi.dll (eg D:\php-5.2.6-Win32\php5isapi.dll) setting it to 'Allowed'.
  6. Update the PATH environment variable to include the php dir eg D:\php-5.2.6-Win32.
  7. Add a new environment variable called PHPRC and set to the php dir eg D:\php-5.2.6-Win32  (this part was missing from the install docs for IIS).
  8. Restart iis (eg run iisreset from the command prompt).

Bingo - that's it. To test create a file called phpinfo.php (and place in the web root) with the following:
<?php
phpinfo();
?>

The critical part to check here is that the output of this phpinfo shows the 'Loaded Configuration File' is set to the php.ini file you created above.  If PHP is configured correctly to use mysql it this (phpinfo output) will have a MySQL section - if this is missing - then something is wrong.

HTH
Tim