Monday, 24 May 2010

Removing whitespace from HTML tags

The Problem

This situation occurs when using the .net 2.0 classes to transform XML into HTML with a style sheet the transform (System.Xml.Xsl.XslCompiledTransform).  the output will include whitespace inside of certain HTML tags that may occasionally display within form fields when output.  This can be a pain especially when displaying TextArea elements. In IE the behaviour appeared to change unexpectedly when some other element appeared before the TextArea – such as a dropdown list (select).

The Solution

A solution is to remove the whitespaces from these tags after it has been transformed.

private string CleanUpWhitespaceInTags(string xmlString)
{
return cleanUpWhitespaceInTagsRegEx.Replace(xmlString, cleanUpWhitespaceInTagsReplacement);
}

private static readonly Regex cleanUpWhitespaceInTagsRegEx = new Regex(@"<(?<tagName>[\w-]+)\b(?<attributes>[^>]*)>\s*(?<content>[^<]*?)\s*</\1>");
private const string cleanUpWhitespaceInTagsReplacement = "<${tagName}${attributes}>${content}</${tagName}>";


The above code uses a regular expression to match tags that have no inner xml/html and gets named captures of the tag name, it’s attributes and content (without any surrounding whitespace).



To break it down:

























































< match the opening tag’s starting brace
(?<tagName>[\w-]+) capture any valid tag name (containing one or more word characters or dashes)
\b check that we are at a word boundary
(?<attributes>[^>]*) capture any characters after the tag name and before an end brace as attributes
> match the opening tag’s end brace
\s* match any whitespace on the left of the content
(?<content>[^<]*?) capture any character that isn’t a starting brace but don’t be greedy
\s* match any whitespace on the right of the content
</\1> match the closing tag


Disclaimer: Whether this regex covers all scenarios has not been tested but it works for the situation we encountered.



The replacement string then reconstitutes the tag, attributes and content without the leading or trailing whitespace.



Technorati Tags: ,,

Friday, 14 May 2010

Properly disposing a System.Threading.Timer

The following test fixture shows how a timer can be properly disposed in order to ensure that the thread executing the callback has completed (or we've timed out waiting for it):

[TestClass]
public class TimerFixture
{
[TestMethod]
public void Check_timer_dispose_behaviour()
{
System.Threading.Timer timer = new System.Threading.Timer(new System.Threading.TimerCallback(OnTick), null, 100, 0);

while (!isProcessing) Thread.Sleep(50);

WaitHandle waitHandle = new AutoResetEvent(false);

timer.Dispose(waitHandle);

isStopping = true;

WaitHandle.WaitAll(new[] { waitHandle }, 1000);

Assert.IsFalse(isProcessing);
}

private void OnTick(object state)
{
isProcessing = true;

while (!isStopping) Thread.Sleep(100);

Thread.Sleep(200);

isProcessing = false;
}

private bool isStopping = false;
private bool isProcessing = false;
}

Wednesday, 24 March 2010

DevWeek 2010

Just got back from DevWeek 2010.  Here is a list of things I need to follow up on from the sessions I attended:

A Day of ASP.NET 4.0 : Fritz Onion

  • MemCache
  • Chart Control
  • GridView/ListView ‘remembers’ selected
  • Query Extender
  • Html Encode syntax and HtmlString class
  • AJAX 4.0
    • Script Loader/Manager
    • Sys.Require
    • Sys.onReady
    • CDN
    • Extender Controls.js
    • Client Templates {{propName}}
    • .sys-template class
    • Sys.create.dataView(“#id”, { data : data })
    • sys: prefix on attributes
    • Sys.bind(Sys.Get(“selector”))
  • Routing in ASP.NET Forms
    • RouteValue, RouteUrl, RouteParameter
  • Web Application rather than Web Site
  • Deployment:
    • Package/Publish, XDT in config files
    • IIS Import on farm
  • .svc services /js to get client proxy
    • [DataContract] [DataMember]
    • live binding {binding Title}
    • Sys.Observer.makeObservable(itemsArray);
    • Sys.Data.DataContext
  • ADO.NET Dynamic Data

97 Things Every Programmer Should Know : Kevlin Henney

  • Bought the book

Objects of Desire : Kevlin Henney

  • Parameter Objects
  • Pass in Context
  • Interpreter / Aggregator Patterns
  • Getter/Setter problem
  • Keep object valid at all times
  • Privatize
  • LSP
  • UML Inheritance Hierarchies
  • Layering: Concept <– Realisation
  • Layering: Domain –> Services –> Infrastructure
  • Apathy, ignorance, selfish
  • Names based on client usage not implementation

VSTS 101 – a beginner’s guide : Brian Randell

  • Project Collection (single db) > Team Project
  • Static Code Analysis
  • Code Metrics
  • Check-in policies
  • Team Build
  • Test impact analysis
  • VS Profiler?!
  • Mostly MS marketing

Agile DB techniques using VS 2010 : Giles Davies

  • Build Screen Saver, Brian the build bunny
  • Extension Properties for schema version number
  • Data Transfer Plan, Data Generation Plan
    • Data bound generator
  • Got to use this!

Intro to Sharepoint 2010 from ASP.NET devs : Fritz Onion

  • VS 2010 makes it easier.  Needs huge buy in.

Entity Framework in .NET 4 and VS 2010 : Eric Nelson

  • Entity Data Model (EDM)
    • Conceptual
    • Mapping
    • Storage
  • Lots of new goodness in 4.0
  • Insert Key
  • Foreign Key surfaced
  • ExecuteStoreQuery
  • EntityFunctions
  • Extension Manager
  • Feature Pack (POCO, code only, self-tracking)
  • Persistence Ignorance
  • http://bit.ly/ericnelson 

Code contracts and design for testability : Dino Esposito

  • Preconditions
  • Postconditions
  • Invariants
  • Interface contracts
  • Tools (rewriter, static checker, asm ref gen)
  • Contract Failure handling (in UT or logging)

Are singletons evil? : Andy Clymer & Kevin Jones

  • Singleton
  • Repository
  • Factory
  • Dependency Injection

Objects of value : Kevlin Henney

  • aka Attribute Object
  • No/insignificant identity
  • Create Value Objects that exist in the domain and ‘wrap’ simple types
  • Systems of Values
  • POVO
  • Patterns of Value : Immutable Value, Copied Value
  • Three finger rule: Identity, State, Behaviour
  • Smells: Anaemia and Multiple Stereotypes
  • Anatomy: Construction, Comparison, Classification and Conversion
  • Domain specific
  • Equals
  • My MonetaryAmount example

Programming with GUTs : Kevlin Henney

  • Things not to test in UT (perhaps in Integration tests)
  • POUT, TDD, DDT
  • Test per proposition not per method
  • Naming:
    • proposition not implementation
    • Underscores
  • Example based
    • Simple cases
    • Common cases
    • Boundary cases
    • Contractual error cases (rainy day)
  • Better roughly right than precisely wrong
  • Black box

Patterns dartboard : Andy Clymer & Kevin Jones

  • Adapter / Proxy
  • Null
  • Active Record
  • Strategy

Is the free lunch over? : Andy Clymer

  • Fork/Join (Parallel.Invoke, Tasks)
  • Pipeline (Queues, production line, stages)
  • Geometric decomposition (Break down the data)
  • Use Sequential version as UT?
  • Parallel Loops (loop of loops, Barrier)
  • Monte Carlo (educated guesses, best result in time T)

Use threads effectively to build responsive & scalable software : Jeffery Richter

  • Threads are bad
  • Threads are good
  • Async Programming Model (APM)
  • ThreadPool and Tasks
  • AsyncEnumerator

Friday, 14 August 2009

T-SQL Cursor Template

This is a handy cursor template for T-SQL on MS SQL Server:
DECLARE curName CURSOR LOCAL FAST_FORWARD
FOR
select *
from mytablename

DECLARE variables

OPEN curName
WHILE 1=1
BEGIN
FETCH NEXT FROM curName
INTO variables

IF @@fetch_status <> 0
BEGIN
BREAK
END

--do work

END

CLOSE curName
DEALLOCATE curName

Friday, 17 July 2009

Writing an event log entry from an ASP.NET application

By default the ASPNET account under which ASP.NET applications cannot write to the registry. So if you are writing an event log entry with a new source it will fail.

The simple answer is to run regedit and go to:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application

Then create a new key with the name of your event source.

Full details can be found here.

Wednesday, 14 January 2009

Using an ASP.NET handler to output a CSV file

I wanted a ASP.NET handler to output some data as a CSV file with the most likely target being to open it in Excel.

I had the following problems to resolve:

  1. Force download rather than opening in IE.

  2. Numbers beginning with zeros (0) must not be stripped off in Excel.

  3. Creating the CSV from an XML file using XSLT.

  4. Decoding entities (e.g. &amp;) in XSLT.

  5. Accessing Session State from the handler code.
So lets look at these in order ...

1. Force download rather than opening in IE.

This one is fairly simple to resolve with some addition of headers:

context.Response.ContentType = "text/csv";
context.Response.AddHeader("Content-Disposition", "inline; filename=\"file.csv\"");

The only thing to look out for here is to use Response.AddHeader rather than the Response.Headers collection as it won't work on most IIS platforms.

2. Numbers beginning with zeros (0) must not be stripped off in Excel.

This solution is a disappointing but effective one. Enclose the number in quotes with a leading equals sign.

So 01234 becomes ="001234"

This is a very Excel bias solution but was good enough for me. Another solution is to lead with a single quote but unfortunately this will initially show in the Excel cell until the user 'edits' the cell then it disappears.

3. Creating the CSV from an XML file using XSLT.

This is fairly straightforward, here's the XSLT:

<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform" msxsl="urn:schemas-microsoft-com:xslt" prefixes="msxsl">
<xsl:output method="text" encoding="utf-8">

<xsl:template match="doc">
<xsl:apply-templates select="row">
</xsl:apply-templates>

<xsl:template match="row">
<xsl:for-each select="*">
<xsl:value-of select="." disable-output-escaping="yes" />
<xsl:if test="position() != last()">
<xsl:value-of select="','" />
</xsl:if>
</xsl:for-each>
<xsl:text>&#10;</xsl:text>
</xsl:template>
</xsl:stylesheet>

This assumes an Xml document hierarchy of doc > row > fields.

This is fine except that often you want to output only certain fields, perhaps in a particular format, and show the field headings in the first row. The above can be adapted for this by swapping out the "for-each" for a "value-of" naming each field individually.

4. Decoding entities (e.g. &amp;) in XSLT.

In the above Xslt you will notice that I have added disable-output-escaping which will do just that.

5. Accessing Session State from the handler code.

The class definition for a handler is by default:

public class CsvHandler : IHttpHandler

To indicate that you need session state too you need to add another interface although this is just a marker (probably should have been an attribute), I only need read access so:

public class CsvHandler : IHttpHandler, IReadOnlySessionState


Okay that covers all the issues listed above.

Visual Studio keyboard layout swaps from UK to US

Solution: Hotkey is Shift+Alt

I've been having problems in Visual Studio where my keyboard would suddenly swap from UK to US layout. From that point on the " key would map to @ and vice versa.

I eventually got round to googling the problem and came to this Microsoft connect item: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=269947

So I learn that there is a hot key - Shift+Alt - that does this and so the problem is reversable. But I have to agree with the person who sent in that item. Why does this hot key exist or perhaps why is it such a simple combo? The only thing I can think of is that MS people testing VS wanted this. To me it is just a pain.