Thursday, 17 April 2008

Cannot resolve the collation conflict T-SQL

Cannot resolve the collation conflict between XXX and YYY in the equal to operation

I recently got this whilst doing some SQL queries that involved joins between two fields with different (albeit very similar) collation types. To stop SQL server from screaming, you'll need to perform a sort of collation cast. The quickest way is to cast one of the field's collation so it matches the other, or you can cast both. Casting to the default database collation is also an option:

JOIN table t ON t.field COLLATE database_default = s.field COLLATE database_default

More info on collate from MSDN.

Sunday, 13 April 2008

Use CSS not JavaScript for rollovers!

Why use Javascript for your rollovers when simple CSS will do? I prefer CSS over Javascript because it degrades better in non-compatible browsers in comparison to JavaScript and it's so straight forward to implement in CSS, just take a peek below...

CSS rollover example in action:

CSS rollover code:

<style type="text/css">
 display: block;
 width: 50px;
 height: 50px;
 text-decoration: none;
 background: url('');
 background-position: -50px 0;
<a class="rollover" href="#">7lt;span class="hidden">Hidden Text</span></a>

Key points about the example

The image used is made up of two images; this is often referred to as a CSS sprite. Having just one image is better than two because you've halved the number of requests needed to retrieve the images, resulting in better site performance. Initially, the first 50×50 pixels of the image is shown (CSS element a.rollover). Then when we activate the rollover with the mouse the CSS element a.rollover:hover is activated, which moves the background image left by 50 pixels this results in a different image being output.

To counteract the loss of text value for the link because images are used (text in links is used by search engine crawlers and screen readers), we have a span that contains text - but the span text is hidden using the display:none; CSS attribute.


There is a great article with some more advanced examples by Dave Shea called CSS Sprites: Image Slicing's Kiss of Death which you should check out.

Thursday, 10 April 2008

How to access the Call Stack C#

As methods are called, information about them are placed on the call stack. The call stack is invaluable in development work for debugging problems, but it can also be useful in other situations (e.g. when logging for an entire app or library is processed by a logging utility in one location).

.NET makes it simple for us to work with the call stack. The functionality is provided via the System.Diagnostics.StackTrace, System.Diagnostics.StackFrame and System.Reflection.MethodBase classes.

Access the call stack via a new instance of the StackTrace class. The stack contains stack frames, these frames represent each method executing on the current thread; programmatically access a frame via a StackFrame instance. Using the StackFrame.GetMethod(), which returns a MethodBase object, you can now easily retrieve the detailed information you wanted. The sample code below demonstrates this.

// First create an instance of the call stack
StackTrace callStack = new StackTrace();

// Next select the frame we want...
// 0 : current frame for the current method
// 1 : Frame that called the current method
// 2 : Frame that called the frame that called the current method
// 3 : get the idea!
StackFrame frame = callStack.GetFrame(1);

// Using StackFrame.GetMethod(), which returns a 
// MethodBase object, we can obtain detailed 
// information about about a method
MethodBase method = frame.GetMethod();

// Get the declaring type and method names 
string declaringType = method.DeclaringType.Name;
string methodName = method.Name;

Friday, 4 April 2008

Configure log4net only once

log4net is a great logging framework with powerful levels of flexibility. This flexibility can result in complexity when used in larger systems. One key point when using log4net in complex systems is to remember to configure the file to log to just once per process.

The file to log to is configured in the call to log4net.Config.XmlConfigurator.Configure() call this just once per process

In complex and constantly changing systems, it isn't always clear whether log4net has been configured. One option is 'if in doubt leave it out', and if you get no logging you know to add the configuration call. But the smart ones out there might disagree with this approach - just as I do! I prefer to just check log4net to see if it is configured before attempting to configure it:

// Only configure log4net once per process
if (!log4net.LogManager.GetRepository().Configured)
    // Call log4net.Config.XmlConfigurator.Configure();
    if (log.IsDebugEnabled)
       log.DebugFormat("Loaded log4net config in {0}.", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Assembly.FullName);
    if (log.IsDebugEnabled)
       log.DebugFormat("log4net already configured for {0}.", System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Assembly.FullName);

Some people might see the immediate logging as unnecessary, but I like to add it so I have a visible record that log4net is correctly configured.

Thursday, 3 April 2008

Removing XmlDocument white space c#

I've recently been working on matching certain API calls with XML data pulled from an XML file for testing purposes. I noticed there was a large amount of white space left in the XML when pulled from the resourced XML file; which is something I didn't want.

I thought setting the XmlDocument.PreserveWhitespace property to false would remove this for me, but it just seems to remove the preceding and trailing white space; making it similar to the string.Trim() method. I needed to use something akin to string.Replace() (this replaces a specific substring with another substring), but more powerful. Here comes the Regex.Replace function to the rescue, which is a bit like string.Replace() on steroids! Regex.Replace() allows replacement of text using regular expressions, something which can make make complex replacements a piece of cake.

Here is the code to replace white space in XML or any XML dialect (such as HTML - or XHTML):

// Remove inner Xml whitespace
Regex regex = new Regex(@">\s*<");
string cleanedXml = regex.Replace(dirtyXml, "><");

Friday, 28 March 2008

HttpHandler for all requests in ASP.Net on IIS

Setting up a HttpHandler for handling ALL incoming requests is straight forward with .Net and IIS. Provided you've created your .Net HttpHandler project to sucessfully handle the requests, you need to do the two following tasks:

1) Ensure that the web.config references the HttpHandler you've created

To the httpHandlers section of your web.config file add a reference to your httpHandler for all HTTP verbs and extensions:

      <add verb="*" path="*" type="your.assembly.reference"/>

2) Setup IIS to route all request to your handler

a) IIS 5 (Win XP)
  • Open the website properties in IIS
  • Select the Home tab
  • Click the Configuration button
  • In new window select the Mappings tab
  • Click the Add button
  • In new window's executable field Browse to the ASP.Net ISAPI dll (usually something like C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll)
  • In the Extension field type .*
  • Untick the Check that file exists box and click OK
N.B. There is a bug that if your OK button is not active you need to click the executable field text box, you should see the middle section of the text in the box change from /.../ to the full file path this should now make the OK button active.
b) IIS 6 (Windows Server 2003)
  • Open the website properties in IIS
  • Select the Home tab
  • Click the Configuration button
  • In new window select the Mappings tab
  • Insert an entry in to the Wildcard application maps with the ASP.Net ISAPI dll (usually something like C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll)
  • Untick the check that file exists box and click OK

You should now see all requests being handle via your handler. If you are having issues, a good place to start finding out why is your IIS logs - but where are my IIS logs?. Good luck!

Wednesday, 26 March 2008

XSLT Transform in C# (a piece of cake)

Whilst there are times when I'd rather be rubbing Dorset Naga chillies in my eyes, most days I'm glad I develop in C# on the .Net framework. Take today for example. I needed to look into manipulating XML via XSLT; a powerful transformation language for XML. I thought it would take a while, around 3 hours; but with the powerful .Net library I had built a win forms app that takes XML input, XSLT input and outputs the transformation - all in under 30 mins! Long live .Net!

Below is the XSLT util class I created for anyone interested.

Tuesday, 25 March 2008

I need some ReST

Despite working hard on two newly released services (BlogIt and Voice SMS) for Esendex there is no time to stop and catch my breath; I've begun working on a completely new ReST API.

With ReST (Representational State Transfer), the idea is that the services are comprised of resources (an item of interest). Calls to ReST services return a representation of a resource placing the client application in a state. Typically a resource provides access to other resources via links. The client uses these links when working with resources, placing the client application in another state, hence the name Representational State Transfer.

ReST is an architectural style, rather than a standard (although it works with recognised standards such as HTTP), there is alot more work with regards to the implementational style rather than just following a set of standards.

I'm quite liking this ReST style:

  • It's simple, lightweight and lacks unneccessary bloat
  • It's built on simple and established standards, following the architecture of the web; no special toolkits are required

I'll keep the blog updated with how it's going in the coming weeks. In the mean time, here are a couple of links you may find useful:

Tuesday, 18 March 2008

DateTime format & globalization problems in ASP.Net

Some problems cropped up recently on a project relating to datetime formats and globalisation. At first glance it seemed that it was related to en-US and en-GB datetime format conflicts. However, it was difficult to figure out why with the machine being setup in the English en-GB globalisation settings?! Turns out that an explicit globalization attribute in the apps config is required to ensure the culture setting is en-GB:

<-- Perhaps something worth adding into the frameworks web.config for all apps? -->
<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="en-GB"/>

This means that dispite the machine being setup in an English en-GB globalisation, .Net was reverting to en-US because nothing was explicitly set.

After a quick Google-woogle, some techie in a forum suggests a way you can force the ASP.Net user to use the system's globalisation settings as follows:

Open up the regional and language settings and navigate to the Advanced tab. Tick the check box which says "Default User Account Settings" and then reboot your server. The culture selected in the regional and language settings should now be picked up by your ASP.Net application.

I haven't tried this yet, but as soon as I get a chance I'll let you know how it goes.

Monday, 17 March 2008

Log4net - problems logging from a web app

There have been a couple of occasions when logging just won't work for me in a web application. This typically means that log4net is getting permission issues. The web application runs as a special user account on the web server called ASPNET (usually). This account has restricted permissions to protect the web server from attacks. By default this account may not have permission to write to the file system. Make sure that the ASPNET account has permission to create and write to files in the directory chosen for logging. If the user has write permissions and logging is still absent, you need to debug log4net; this luckily is alot easier than it sounds.

Firstly, we need to output all internal debugging messages; add to your web.config the following appSettings:

 <add key="log4net.Internal.Debug" value="true"/>

Internal debugging messages are written to the console and to the System.Diagnostics.Trace system. An ASP.Net application does not have a console, therefore messages will be will be lost. The Trace system will by default send the message to an attached debugger (where the messages will appear in the output window). If the process does not have a debugger attached then the messages are sent to the system debugger. A utility like DebugView from may be used to capture these messages.

As log4net internal debug messages are written to the System.Diagnostics.Trace system it is possible to redirect those messages to a local file (which is my preferred method). You can define a trace listener by adding the following to your application's web.config file (ensuring write permissions are enabled and dir exists):

<trace autoflush="true">
     initializeData="C:\tmp\log4net.txt" />

Saturday, 15 March 2008

SQL - Replace line breaks and other characters

I'm not quite as proficient with SQL as I'd like, so when I stumble across little SQL gems I know I'll use again I like to note them down; what better a place to do that than my blog to share with the rest of the web :)

This is a Transact SQL example, on how to replace a character on a select. The character being replaced is just the ASCII code of the character.


I find this very useful when replacing line breaks with a space on a selected field:

SELECT REPLACE(MyField, CHAR(10), ' ') FROM MyTable

Other frequently used characters you may want to replace:

Tab -> char(9)
Line feed -> char(10)
Carriage return -> char(13)

Wednesday, 12 March 2008

Update your Blog by SMS wherever you are

BlogIt is a new, free service mobile blogging service available to all new and existing Esendex users. Whether you are a personal blogger or professional journalist, BlogIt is the perfect tool for updating your blog when you are on the move - just submit your posts by SMS message.

Validated posts can be online within seconds, ensuring that fast moving, topical events are shared as quickly as possible.

  • Respond to developments, news and comments immediately, your texts are posted straight away
  • Update your blog whilst on the move, or away from your PC, at anytime of day or night
  • Capture thoughts, opinions and ideas straight away 
  • Free to use - you simply pay your standard rate to text in your blog entries

BlogIt Prices

BlogIt is free to register and use, so there's no better excuse to sign up. There are no hidden charges - you simply pay your standard rate to send in your posts.

Registration and set-up takes just a few minutes then you can start mobile blogging straight away. Just text your blog entries to 07786 204 255. Each entry can be up to a maximum of 612 characters.

Sign Up Now!

If you're new to Esendex's services Sign up as a user now and you can start using BlogIt within minutes.

If you are already an existing Esendex customer simply log in from the home page and update your BlogIt details from My Details.

Friday, 29 February 2008

Clear Concise HTTP Status Codes List

I've recently been looking into ReST services, and needless to say you need to know your HTTP status codes. These are a set of standardised response codes given by web site servers on the Internet. The codes help identify the cause of the problem when a web page or other resource does not load properly. Here is a concise list for reference purposes.

 Information                    # 1xx
    Continue                       # 100
    SwitchProtocl                  # 101
 Success                        # 2xx
    OK                             # 200
    Created                        # 201
    Accepted                       # 202
    NonAuthoritativeInformation    # 203
    NoContent                      # 204
    ResetContent                   # 205
    PartialContent                 # 206
 Redirection                    # 3xx
    MultipleChoice                 # 300
    MovedPermanently               # 301
    Found                          # 302
    SeeOther                       # 303
    NotModified                    # 304
    UseProxy                       # 305
    TemporaryRedirect              # 307
 ClientError                    # 4xx
    BadRequest                     # 400
    Unauthorized                   # 401
    PaymentRequired                # 402
    Forbidden                      # 403
    NotFound                       # 404
    MethodNotAllowed               # 405
    NotAcceptable                  # 406
    ProxyAuthenticationRequired    # 407
    RequestTimeOut                 # 408
    Conflict                       # 409
    Gone                           # 410
    LengthRequired                 # 411
    PreconditionFailed             # 412
    RequestEntityTooLarge          # 413
    RequestURITooLong              # 414
    UnsupportedMediaType           # 415
    RequestedRangeNotSatisfiable   # 416
    ExpectationFailed              # 417
 ServerError                    # 5xx
    InternalServerError            # 500
    NotImplemented                 # 501
    BadGateway                     # 502
    ServiceUnavailable             # 503
    GatewayTimeOut                 # 504
    VersionNotSupported            # 505

To get more info on these codes check out the page on Status Code Definitions.

Wednesday, 27 February 2008

Windows 2003 IIS returns 404 for ASP.Net pages

Had an issue on one of our externally managed servers which wouldn't process any ASP.Net documents (aspx, asmx etc), but would just return a 404. However, it would happily return other files such as htm, txt, css. There was no web application logging, no logs in event viewer I had nothing to go on, until I remembered about the often forgotten and rarely used IIS logs (see my article on where are my iis logs to find yours :).

The logs showed requests for the ASP.Net documents and that a 404 was being returned. This part wasn't helpful but the logs also provide a sub status code which was 2:

#Fields: date time s-sitename s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip sc-status sc-substatus 
2008-02-27 12:39:13 W3SVC2 GET /default.aspx - 80 - 404 2

A quick Google led me to Microsofts IIS 6 pages explaining the sub status codes - bingo!

404.2 : "Web service extension lockdown policy prevents this request"

Knowing this and with the power of Google I resolved the issue in less than a minute. Just open the IIS6 interface, select the Web Service Extensions menu node, on the right you will see the web service extensions available - just select the ASP.Net extension and click the allow button.

IIS Web Extensions Menu

Wednesday, 20 February 2008

ASP.Net Production Web Server Top Tip

There are a number of things we want to ensure on our production servers:

The debug attribute in the compilation element in the web.config should be false for all applications. This is mainly for performance reasons, leaving it to false means:

1) The compilation of ASP.NET pages takes longer (since some batch optimizations are disabled)

2) Code can execute slower (since some additional debug paths are enabled)

3) Much more memory is used within the application at runtime

4) Scripts and images downloaded from the WebResources.axd handler are not cached

Page output tracing should be disabled, again for performance reasons.

The customErrors element should be in remoteOnly mode. This means the custom error page will be shown to remote users rather than the actual exception or error message. We never want to output visible errors to users!

Luckily, we can ensure all the above happens using one simple config setting in the machine.config on the web server:

   <deployment retail="true" />
<system.web />

Additional info can be found in the MSDN documentation.

Control name changes due to xhtmlConformance

Another strange and unwanted ASP.Net problem cropped up today when we least needed it to. We had some code problems occurring on some servers, but the exact same code worked fine on other servers. The problem was related to some code that hadn't changed for a long time, and left the development team scratching our heads.

Turns out in the HTML the naming convention for controls were different for controls rendered between the different sets of servers. The HTML control name attributes that were separated by a colon : were now being separated by a dollar sign $ in the name property, the id attribute however stayed constant.

This would cause problems in certain scenarios for Javascript and Serverside parsing of the html form values; basically anywhere the element name was hard coded using the : seperator would now not find the control.

The problem relates back to our transition from .Net 1.1 to .Net 2 (so I'm surprised this took so long to surface) and a similar problem that cropped up with some AJAX integration a while back to do with an xhtmlConformance setting.

ASP.Net 1 and 1.1 did not emit XHTML compliant markup from countless server controls. ASP.Net 2 changed this and defaults to emitting XHTML compliant markup from all controls. Beta testing of ASP.Net 2 showed Microsoft that this could affect certain web apps and to prevent this a xhtmlConformance setting was introduced and added in the conversion to the framework's web.config file:

   <xhtmlConformance mode="Legacy" />

Basically, with the setting set to legacy the following example html control output would be rendered:

<input type="text" name="ParentControl:Control" id="ParentControl_Control" />

With the setting set to Transitional (Default) or Strict the following example html control output would be rendered:

<input type="text" name="ParentControl$Control" id="ParentControl_Control" />

I would recommend you don't set the setting to Legacy and leave it as the default Transitional or set to Strict as this will result in your HTML from your server controls to be well formed (i.e. all tags are closed for all elements). Important in ASP.Net AJAX implementations as mentioned in this post.

Friday, 15 February 2008

Split a text file with VBScript

I had to split some text reports (csv format) that are read by colleagues in Excel just the other day. Excel can only read ~65k lines on one sheet, but the reports were ~100k lines - so I had to split the files in two. The reports are generated via script; so I decided to write another script to split the files at around the 60K mark. Hope this can save someone else some time :)

The script below takes as arguements; source filename, base filename and the target directory.

if WScript.Arguments.Count > 0 then

 ' retrieve the command line arguments
 sourceFile = WScript.arguments.Item(0)
        basename = WScript.arguments.Item(1)
        targetDir = WScript.arguments.Item(2)
 set objFSO = CreateObject("Scripting.FileSystemObject")

 ' check the file exists
        if objFSO.FileExists( sourceFile ) then
  WScript.Echo ("input file exists...")

  ' new files
  new1 = targetDir + "\" + basename + "_" + "a." + objFSO.GetExtensionName(sourceFile)
  new2 = targetDir + "\" + basename + "_" + "b." + objFSO.GetExtensionName(sourceFile)
  set fs = CreateObject("Scripting.FileSystemObject")  
  set w1 = objFSO.CreateTextFile(new1, True)  
  set w2 = objFSO.CreateTextFile(new2, True)  
  isNotSplit = True
  with fs.OpenTextFile(sourceFile)  
   while Not .AtEndOfStream  
    if .Line < 60000 then  
     w1.WriteLine .ReadLine  
     w2.WriteLine .ReadLine  
     if( isNotSplit ) then
      isNotSplit = False
      WScript.Echo ("file being split...")
     end iF
    end if  
  end with  
  if( isNotSplit ) then
   WScript.Echo ("input file not split...")
   WScript.Echo ("input file split...")
  end if
  WScript.Echo ("input file does not exist...")
 end if
 WScript.Echo ("finished!")
end if

HTML Email Newsletter Top Tips

Email newsletters are common place for advertising products, services and events. Considering it's uses, it is easy to understand why html newsletters are king; who wants to send plain text emails when we can send fancy text and graphics?! Below are some simple tips to get you started with your html email newsletter creation.

1. Tables for layout not CSS... Unfortunately, there are alot of email clients that were developed in the last ice age still being used. This means CSS is poorly and wildly interpreted in terms of displaying your newsletter's layout. It's back to tables for cross email application consistency.

2. Inline styles... Although CSS shouldn't be used for layout, it is fine to use simple CSS stlying for the content of the email newsletter. Some email clients can strip out html head styles, so put the <styles section in the body tag, or even better, put the css styles inline.

<p style="color: red;">

3. Javascript... Put simply, no JsvaScript! Most email clients will just strip it out.

4. Test, test and test... First test the design in Firefox and IE, chances are if it works in these then you should have a consistent design across the web email clients and most app email clients. Finally test with as many email applications as possible (outlook, outlook express, thunderbird, lotus notes etc).

Using the above tips you should achieve a fairly consistent viewing experience of your newsletter for recipients. If you are having consistency issues the links below may help.

A Guide to CSS Support in Email A top compatabilities article
Example table layouts
Useful email marketing blog
CSS support in HTML emails of Hotmail, Yahoo! Mail and Gmail
CSS and Email, Kissing in a Tree

Thursday, 7 February 2008

Finding a User Mac Address (Javascript)

Unless a user is on an internal network, there is no way server-side (I know of) to retrieve the mac address of a user accessing a web page, simply because it isn't sent in the http headers for a request. Any attempt to analyze the underlying network communications server side is pointless as it will just return the MAC address for the last routing machine. However, it is possible to retrieve the mac address of the user simply using client-side Javascript in IE.

Once you've accessed the WMI and got the MAC address you can even send the value server-side if necessary.

Implications: You are connecting to the WMI (Windows Management Instrumentation) for the local machine and therefore you may have a problem if your IE security settings are restrictive. Also, this won't work in non-IE browsers; only works for Windows operating systems. Not all that restrictive then?! ;)

Troubleshooting: If you get an 'automation server can't create object' error when running the script it is probably for one of the reasons below.

  • You need to enable 'Initialize and script ActiveX controls not marked as safe' on the security tab -> custom level options in IE
  • WMI isn't installed correctly
  • WMI isn't installed
  • Some other permission issue. Are you an administrator? If on Windows 2000 server, have you installed sp4?

P.S. Another plausible option is to use an ActiveX control in connecting to WMI.

Friday, 1 February 2008

Could not load file or assembly App_Web_XXX

Came across a completely random exception today on a new web server:

System.IO.FileNotFoundException: Could not load file or assembly 'App_Web_XXX, Version=, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. File name: 'App_Web_XXX, Version=, Culture=neutral, PublicKeyToken=null'

After some digging, I found issue is now resolved in .Net 2 SP1, which I recommend you all download if you haven't done so already. You can alternatively download the individual fix for this from Microsoft Support. If you are unable to install the fix or service pack there are a couple of workarounds that may work:

1. Editing the aspx file throwing the error (if appropriate)
2. Clear the Temporary ASP.Net Files folder and restart the application pool
3. Setting batch="false" in the web.config file compilation section (it is true by default)

All the workarounds are fairly simple and harmless except option 3. This has other performance implications; therefore may not be the best option for a production environment.

Wednesday, 30 January 2008

Where are my IIS Logs?

Although you may have bucket loads of logging taking place in your web applications/sites, you may still feel the need to make use of the IIS logs. Use the following steps to track down these hidden away log files:

  1. Open Internet Information Services (IIS)
  2. Right-click the desired web site and select properties
  3. On the Web Site tab, at the bottom is the Active Log Format; select the properties button next to it
  4. You'll now have a box that contains the log file directory and the log file name. Together they make the full log path.

In this window you can also change useful settings like what request/response details are recorded in the logs. Some useful options not selected by dfault are bytes sent, bytes received and referrer (useful for tracking 404s in certain cases).

Extracting useful info from these log files is another blog post all together ;)

Monday, 28 January 2008

User is not associated with a trusted SQL Server connection

Login failed for user 'username'. The user is not associated with a trusted SQL Server connection.

This error had me scratching my head today for around 30 mins (mainly because I rarely setup SQL Server instances from scratch), and took me just 30 secs to fix.

Basically the SQL server instance you are conecting to has been configured to operate in Windows Authentication Mode and doesn't allow the use of SQL accounts. So change the Authentication Mode of the SQL server from Windows Authentication Mode to Mixed Mode (Windows Authentication and SQL Server Authentication). To do this right click your SQL Server instance in Enterprise Manager/Management Studio, select security and you should see the option in there. Hope you didn't waste as much time as I did on this :)

ASP.Net AJAX Not Working (Full page postback)

The conversion process from VS 2003 to VS 2005 for web projects may result in strange behaviour when adding new client-side JavaScript to the project. For me this was evident when using ASP.Net AJAX UpdatePanel controls, which resulted in a page performing a full-page postback instead of a partial page postback of the desired AJAX page elements.

ASP.Net 1 and 1.1 did not emit XHTML compliant markup from countless server controls. ASP.Net 2 changed this and defaults to emitting XHTML compliant markup from all controls. Beta testing of ASP.Net 2 showed Microsoft that this could affect certain web apps and to prevent this a xhtmlConformance setting was introduced and added in the conversion to the config file:

   <xhtmlConformance mode="Legacy" />

If you are having ASP.Net AJAX issues I recommend removing the <xhtmlConformance> section from your web.config file or perhaps set it to Transitional or Strict.

The good new about this is it will result in your HTML from your server controls to be well formed (i.e. all tags are closed for all elements). Important in ASP.Net AJAX implementations because AJAX dynamically replaces the contents of HTML elements on your web page. If the tags aren't well formed, the AJAX JavaScript can get it's knickers in a twist with regards to the containers it should be updating, resulting in big problems.


It's also worth checking the framework's web.config file for the setting if you think this is affecting you and the setting isn't in your app's web.config

Tuesday, 22 January 2008

Browser CSS Differences (IE6 IE7 Firefox)

Typically the 3 major browsers used are Firefox, IE6 and IE7. Perhaps you thought they would behave the behave the same when rendering CSS in the browser window? If only life were that simple.

Although Firefox and IE7 and more similar than ever in rendering CSS, IE6 has always had a mind of its own, adding padding and spacing amongst other things in random locations. However, there is a simple way to cater specifically for the major browsers. IE6 recognises underscore lines, but IE7 does not. IE6 and IE7 recognise period lines. For example...

margin-top: 8px;
.margin-top: 10px;
_margin-top: 4px;

Firefox, and every other non-IE browser, will only see and use the 8px, IE6 will see the 10px line, but then the 4px line will stomp on it, and only IE7 will see the 10px line. You can now support all major browsers without having to write a serverside script, clientside script or even a horrible CSS expression :)

Regular Expression for a GUID

Just a quick post, if you ever need a regular expression to match a guid, for example - in a URL, then look no further :)


Thursday, 17 January 2008

Getting Started with Profiles In ASP.Net 2

Profiles In ASP.Net 2 uses the same provider-based structure used by ASP.NET membership and role management amongst other features. ASP.NET includes a profile provider that stores data using Microsoft SQL Server. The default ASP.NET machine.config contains a default SqlProfileProvider instance named AspNetSqlProfileProvider that connects to SQL Server on the local machine. By default, the ASP.NET profile feature uses this provider. You can alternativly specify another in the web app's web.config (step 3). The simple steps below should get you started using Profiles in your .Net 2 web apps:

  1. Create the database using the ASP.Net Profile Providers MSDN article.
  2. Create your profile section in your web app's web.config file:
  3. Specify your custom SQL database if not using the default from the machine.config but updating your web.config:
  4. Start using your Profiles for authenticated users:

Profiles in .Net generally have alot more to them then what I've detailed above, the links below should help you get started:

Wednesday, 16 January 2008

JavaScript Syntax Highlighter for C# SQL XML VB and more

To bring your code to life on your blogs/web sites there is a great syntax highlighter written in JavaScript simply called Syntax Highlighter and best of all's free! Supported languages/markup include C, C++, C#, CSS, Delphi, Java, javaScript, PHP, Python, Ruby, SQL, VB, XML, HTML - see the C# example below:

To get it running on your pages; download the files from the Syntax Highlighter site to your server, on your web page just pull in the CSS file, the required JS files (according to your language choices) and set some JS values on page load:

<link href='/css/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>

<script type='text/javascript' src='/js/shCore.js'/>
<script type='text/javascript' src='/js/shBrushCSharp.js'/>
<script type='text/javascript' src='/js/shBrushXml.js'/>
<script type='text/javascript' src='/js/shBrushJScript.js' />

<script type='text/javascript'>
window.onload = function () {
    dp.SyntaxHighlighter.ClipboardSwf = '/flash/clipboard.swf';

Once this is set up you can just place your code on the page surrounded by pre/textarea tags. Then specify a class according to the language alias you wish to use (aliases are listed on the Syntax Highlighter site).

<textarea name="code" class="c#" cols="50" rows="10">
... some code/markup here ...

Monday, 14 January 2008

IHttpHandler IsReusable Property

There isn't much clear info regarding this property on the net. It can be better in terms of performance when the property is set to true, but can cause some headaches if you have set it to true in the wrong scenario.

public bool IsReusable
      return false;

The property is used to indicate if a single intantiation of your IHttpHandler implementation can be used to process multiple concurrent requests. Each client request is considered to be a worker thread on the serverside when being processed through the ASP.NET pipeline. So, if we set IsReusable = true, we need to make sure that our ProcessRequest method is threadsafe. The ProcessRequest should not rely on any state that could be modified by other concurrent request threads. Important when your IHttpHandler implementation does expensive initialisations, otherwise it probabaly doesn't really matter if you return true or false (since simple object allocation is fairly inexpensive in .NET). N.B. Pages are never pooled.

Monday, 7 January 2008

System.Web.HttpException: Maximum request length exceeded

The HttpRuntimeSection.MaxRequestLength is a property new to the .Net 2 framework, which is used to control the maximum request size in kilobytes for a web app. The default size is 4096 KB (4 MB), and the property is useful for preventing DOS (denial of service) attacks caused by site users posting large files to the server.

If you are uploading large files to a web app you may find the property retricting and you'll need to override the default value of this property to something you can work with. You can do this by modifying your web.config or machine.config, although I suggest setting a new value for this property in web.configs (on a per web app basis) as it would be unlikely you need all the web apps on a server to have a large upload limit and this may open up your web server to increased risk of DOS attacks.

    <httpRuntime maxRequestLength="XXXX" />

MSDN info on modifying your HttpRuntimeSection.MaxRequestLength property.