A catalogue of my discoveries in software development and related subjects, that I think might be of use or interest to everyone else, or to me when I forget what I did!

Textbox CrLf in Firefox using AJAX UpdatePanel

February 17, 2009

When using a MultiLine textbox inside an ASP.NET AJAX update panel, you may encounter problems with carriage return line feeds in your text on the server using Firefox (and potentially other browsers). Internet Explorer uses the Windows style CrLf (13 10) for newlines in a textarea but Firefox uses Unix style Lf (10) only. On a synchronous postback it seems ASP.NET fixes this and you will get CrLf in your text on the server. However, when you are posting back asynchronously using AJAX, you only get Lf in your text when Firefox is used. In order to clean this up and have consistant data, I wrote a simple regex replace to make sure all Lf are preceded by a Cr.
public static string CleanUnixCrLf(string textIn)
   //firefox only uses Lf and not CrLf
   return System.Text.RegularExpressions.Regex.Replace(textIn, "([^\r])[\n]", "$1\r\n");
Permalink: Textbox CrLf in Firefox using AJAX UpdatePanel

Regular Expression Tools

February 02, 2009

A useful thing to have as a developer is a tool for testing your regular expressions as you build them.

There are many out there, but I have two particular favourites.

  • For simple testing when building a regex, I like to use 'RegexBuilder'. It has a very simple and quick off the mark interface where you can start typing your regex with 2 testing texts to see if it is working properly:

    REB Screenshot

  • For more advanced testing data, or to check the output based on replaces, splits, plus many other useful features, I like to use 'The Regulator'. This has a lot of useful functionality and will help you building regular expression syntax if you are unsure.

    Regulator Screenshot

I would recommend having both of these programs, as they both have their uses, they are both easy to use and between them can cater for most (if not all) of your regular expression testing needs!
Permalink: Regular Expression Tools

ASP.NET Multiple Page Load Problem

January 13, 2009

I've had this problem many a time and every time I get it again I forget what the cause was; This time I'm going to blog it!

I have encountered three similar situations where ASP.NET fires the page_load event twice, or more.

  1. In one scenario (on a postback) your page load gets called once for the postback (IsPostback = true) and then gets called again, with IsPostback = false, which can cause a world of mistery until you realize what is happening!

    This is normally caused when using a GridView with an asp:ButtonField using ButtonType=Image. This is bug in the .NET framework which can be solved by using an asp:TemplateField with an asp:ImageButton defined within it.

  2. Another scenario is you get two or more page loads everytime you load the page, whether it is a postback or not. This is usually caused by one of your HTML elements referencing "" (blank) or "#" as a source for its data (e.g. image src="", or background="#ff0000"). This is because this source string is interpreted by the browser as a relative url (which will be the current page) and therefore the browser makes a request for the page for each HTML element that 'references' it.

    To workaround this issue, make sure your images etc. reference at least something, even if it is '%20'. Also use CSS for any colouring, not HTML attributes.

  3. Another example I have found more recently, is when using as asp:ImageButton within a template field of a databound control, where the imageUrl (src) does not exist on the server (404) will cause firstly two postbacks both with IsPostback=true, but will not raise the click event. This problem does not exist in IE, but does in Firefox and potentially other browsers. To fix this, make sure that the image source of an image button exists on the server.

Permalink: ASP.NET Multiple Page Load Problem

Visual Studio, Cassini, IIS and Debugging

January 07, 2009

If you develop ASP.NET websites, you are probably aware that instead of using the built in Visual Studio Web Server (Cassini) for debugging, you can use IIS. If you have configured this for your project, Visual Studio creates a virtual directory in IIS and pressing F5 to debug won't start the built in server but will instead attach to the IIS website. Using IIS over Cassini has several advantages, however, it still doesn't allow you to edit the source while you browse the site and virtual directories can be a pain when the live site will be running from root. I prefer to leave these project settings alone and instead add an entirely new site in IIS, pointing at the codebase. This gives you more control over how the development site can be accessed and you can configure each site to use different SSL certificates, filter on host header values etc. This allows easy browsing of the latest version of the development site, and allows you to quickly make changes to the source code, recompile and refresh. Since you are doing all of this outside of the debugger you can edit source code while keeping an eye on how the changes are affecting the site. The only problem with this is if you are in the middle of using the site and you find a bug that you need to trace using the debugger, which of course isn't running in the current context. You can overcome by using the 'Debug > Attach to Process' menu and then selecting w3wp.exe. This will attach to the IIS process to and Visual Studio will load the debug symbols for the sites you are running, thus allowing you to set breakpoints in the code which will be fired by any browser triggering that line of code (also useful when you are testing accross multiple browsers). This is quite a few keystrokes to get the debugger up and running, but fortunately Visual Studio allows you to create macros and assign shortcuts to them. I found a tutorial on how to create a macro that will attach to IIS and how to set up the shortcut. I set up my shortcut key as CTRL+0 which is an easy sequence to remember. The macro that is listed on the above link did not work on my machine, because I am on a domain. I edited the script to tidy it up and to make it more robust, below:
Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics

Public Module AttachToIIS
    Sub Attach()
            Dim dbg2 As EnvDTE80.Debugger2 = DTE.Debugger
            Dim trans As EnvDTE80.Transport = dbg2.Transports.Item("Default")
            Dim dbgeng(3) As EnvDTE80.Engine
            dbgeng(0) = trans.Engines.Item("Managed")
            dbgeng(1) = trans.Engines.Item("Native")
            dbgeng(2) = trans.Engines.Item("T-SQL")

            Dim proc2 As EnvDTE80.Process2 = dbg2.GetProcesses(trans, Environment.MachineName).Item("w3wp.exe")
        Catch ex As System.Exception
        End Try
    End Sub
End Module
If you get the error 'Invalid Index' it generally means that IIS has not loaded the application since a recompile, so you need to refresh the page in your browser first to reload it.
Permalink: Visual Studio, Cassini, IIS and Debugging

Data Binding to an Extension Method

December 10, 2008

If you have defined extension methods to your entities in your BLL, (for example to format the output, or amalgamate some result) you may wish to display the return value of the extension method in a bound control, such as an ASP.NET GridView. In order to access an extension method, you have to import the containing namespace into the codefile you are working with. The problem is that the bindings are being evaluated by the DataBinder, so even if you import the namespace using the @import directive into the page, the extension methods are only available to your code-infront code blocks, not the ASP.NET DataBinder. In order to achieve this goal, you should Import the namespace as above using @import and instead of using a BoundField, use a TemplateField (but don't use Eval or Bind), simply cast the Container.DataItem back to the extended type and manually add the call to the extension method.
<%@ Import Namespace="eCommerceFramework.BLL.EntityExtensions" %>


<asp:TemplateField HeaderText="Price">
                <%# FormatCurrency(DirectCast(Container.DataItem, DDL.DTOs.ShopBundle).TotalPrice(),2) %>
Generally speaking, I wouldn't imagine you would be 2 way data-binding on an extension method, but if you need to make the value retreivable, put it into a runat="server" control (label/textbox) and give it an ID you can use for FindControl.
Permalink: Data Binding to an Extension Method

Matching Tags using Regular Expressions Balancing Groups

November 28, 2008

The regular expressions engine provided by the .NET Framework includes a new feature known as 'balancing groups'. This feature allows you to increment/decrement the match count of a named capturing group by giving the group a positive and negative match context. You can then test to see you have an equal number of matches, by testing if the group has a value (i.e. an effective zero result means the group was balanced). You can include this syntax in your match pattern, so that only the balanced result is considered a match. Microsoft don't really go into this much and only show a small example of matching opening and closing paranthesis. In my case, I wanted to match a specific chunk of HTML code in a file and then find the closing tag to matching the name of the opening tag. For example:
  <div class="targetContent">
   Something in here
   <div> Something else in here</div>
Using standard regular expressions, searching for <div class="targetContent"> to </div> can work in two ways. Non-greedy mode, matches on the </div> of the inner div. In greedy mode, it matches all the way to end of the outer div. What I wanted to do, is match on the last </div> that makes the tags balance, which can be done using balancing groups! C# Code:
pattern = "<div class=\"targetContent\">.*?((?<TAG><div).*?(?<-TAG></div>))?(?(TAG)(?!))</div>";
Effectively, what the expression does is:
  1. Start the match from the div with class="targetContent"
  2. Match any internal content
  3. Whenever it encounters another div tag, it increments the TAG count
  4. Match any nested content
  5. Whenever it encounters another closing div tag, it decrements the TAG count
  6. It becomes a match when the tag count is equal
  7. Finally match on the closing tag of our outer div
This can be applied to any XML style markup, where you have the notation of opening and closing tags.
Permalink: Matching Tags using Regular Expressions Balancing Groups

LINQ Select Distinct on Custom Class Property

November 18, 2008

The standard LINQ .Distinct() function will pass your IEnumerable items to the 'default comparer' to differenciate the items. If your IEnumerable contains objects of an arbitrary class you would ordinarily have to create a IEqualityComparer to compare the relavent property of each instance. This seems like too much work just to simply remove objects that have a duplicate property value. I came up with a workaround for this using the 'group' keyword to group your objects by the target property and to then select the first record from each group, using the 'First' extension. C# Example:
   var distinctByWeekNum = from e in allUserEntries
                           group e by e.WeekNumber into g
                           select g.First();
The above example basically selects all objects that are distinct based on the 'WeekNumber', by first grouping items with the same 'WeekNumber' together and then selecting only the first item from each group (thus dropping any duplicates).
Permalink: LINQ Select Distinct on Custom Class Property

ScriptManager Service Reference and HTTPS

November 05, 2008

If you use the ASP.NET AJAX script manager with a service reference to a local WCF service, then you may encounter problems when using HTTPS on the page. If you have not configured your service for use with HTTPS you will most likely receive 'xyzService is not defined' errors in your Javascript. This is because when you add a service reference to '~/Services/xysService.svc' the AJAX Script Manager will import '~/Services/xyzService.svc/js' (or '~/Services/xyzService.svc/jsdebug') to define the prototypes for calling the service. This will return a '404 - Page Not Found' error when using the HTTPS protocol. In order to register the service for use over HTTPS you need to create a configured binding for this:

       <binding name="webHttpsBinding">
         <security mode="Transport"></security>




    <service name="WebNs.xyzService">
    <endpoint address="" behaviorConfiguration="WebNs.xyzServiceAspNetAjaxBehavior"
     binding="webHttpBinding" bindingConfiguration="webHttpsBinding" contract="WebNs.xyzService" />
This configures your service to serve up over HTTPS. Make sure you add the HTTPS binding in IIS for this to work!
Permalink: ScriptManager Service Reference and HTTPS

ASP.NET URL Rewriting and Tilde

November 04, 2008

In ASP.NET controls you can use the tilde '~' character to signify the virtual application root of the website, for example when sourcing an image for an ImageButton. Code:
  <asp:ImageButton ID="ImageButton1" runat="server" AlternateText="Example Button" ImageUrl="~/images/button.png" />
This is fine for most cases. However, when using URL rewriting (via HttpHandlers) it can become a problem, since ASP.NET will calculate the path to the resource based on the location of the physical page it is rendering (not the page requesed in the browser [RawUrl]). If the resource is in a directory below the page directory, then it will render a relative path to the HTML, (and not an absolute path from the app root). When your browser sees a relative path in the HTML it appends that to the current working directory to retreive the resource, which for a page being served up via a rewrite, is probably the wrong directory. For example, imagine you have the following directory structure: /MyButtonPage.aspx /images/button.png /subdir/page-served-by-httphandler-mapping-to-mybuttonpage.aspx If you view '/MyButtonPage.aspx' (containing the code from above) the output path to the image would be 'images/button.png'. Your browser will therefore retreive '/images/button.png' which is correct. However, if you view '/subdir/page-served-by-httphandler-mapping-to-mybuttonpage.aspx' (which rewrites internally the '/MyButtonPage.aspx') then ASP.NET will again render the image path as 'images/button.png' (since it is relative to the 'MyButtonPage.aspx' which was rendered internally). Your browser will now try to retrieve, '/subdir/images/button.png' which does not exist. A workaround for this problem is to not use the tilde mechanism and instead reference the absolute path to the resource in the code. e.g.
  <asp:ImageButton ID="ImageButton1" runat="server" AlternateText="Example Button" ImageUrl="/images/button.png" />
However, this will reference from the website root, not the application root, so be careful if your site runs as a virtual application within another site.
Permalink: ASP.NET URL Rewriting and Tilde

Safe Rewriting URL Encoder

October 30, 2008

When using URL rewriting to make nice URLs without querystrings, it is useful to include a meaningful name for the page, i.e. the page title, in the URL itself. This helps usability in distinguishing pages and also aids search engines in spidering different content that may be generated by a single page on your server. For some reason, the HttpUtility.UrlEncode and HttpUtility.HtmlEncode just dont cut it for making good URLs that are readable, optimized and work on the browser/server. I have written my own class for cleaning/encoding text into a form that can be used as part of a URL that will be used in a rewriting engine. Code:
Imports System.Text.RegularExpressions

Public Class UrlEncoder
    Public Shared Function EncodeRewriteUrl(ByVal inputString As String) As String
        Dim url As String = Regex.Replace(System.Web.HttpUtility.HtmlDecode(inputString.Replace(" ", "-")), "[^a-zA-Z0-9\-]", "")
        While url.Contains("--")
            url = url.Replace("--", "-")
        End While
        Return url
    End Function
End Class
The idea here is that you pass in the text you want to use as your URL, and you receive a hyphenated URL containing only URL safe characters ready for use with your rewriting engine. Example: if.. pageId=1 pageTitle="A page about 'dogs' and 'cats' (also other things)" and.. pageUrl=UrlEncoder.EncodeRewriteUrl(pageTitle & "-" & pageId & ".aspx") then.. The page URL would be: A-page-about-dogs-and-cats-also-other-things-1.aspx
Permalink: Safe Rewriting URL Encoder