Tag Archives: ASP.NET

Windows Server 2008, ASP.NET, Pre-compiling and Virtual Directories

windowsserver2008 There has been an interesting problem at work over the last couple of weeks. We are in the process of preparing to move service providers and at the same time upgrading all our servers to run Windows Server 2008 and SQL Server 2008. In preparation for this move, we have been upgrading our staging and test servers so we can be sure that everything will work as expected and to iron out the processes, so the move goes as smoothly as possible.

It took about ten minutes before we hit the strangest of problems. It was focused around the way we use a virtual directory to share common code and controls across different websites. The premise is that you create a project to hold your common javascript/images/ascx controls/web services and so on. You then use a virtual directory inside each of your websites that points to the common project. With only a small amount of tweaking for the common ascx controls everything seems to work without too much trouble. That is, until you try to do this on Windows Server 2008.

When we started up our web application on our new environment, we noticed almost immediately that the AJAX calls that used the common web service were failing. The error message was suggesting that the project that contained the common web service has not been compiled correctly. By copying the website across to a Windows 2003 server, we deduced that the problem was specific to 2008 as it worked perfectly on 2003. Having exhausted all the developers ideas on why this would be, we called Microsoft and got them involved in troubleshooting the issue.

A few days later an answer came: do not pre-compile your website. Sure enough, build the website without pre-compilation and it worked perfectly. Microsoft’s explanation was that it was due to a change in the way that Windows Server 2008/IIS7 worked. Fairly cryptic I must say and certainly does not leave me satisfied as to why it would not work and what have they done to stop it working. For us, using Windows Server 2008 and IIS7 is more important than the slight performance hit you get when deploying without pre-compilation. For others it may not be such a desirable solution.

jQuery Inline Confirm

I have been using Delicious social bookmarking service ever since Blinklist degraded and finally lost the plot with their new design. When I first started using Delicious, a feature of their interface really leapt out at me and I could not wait to include it into a project.
The feature I am talking about is their inline confirmation. That is, when you, for instance, delete a bookmark by clicking on the delete link, the link is replaced with an ‘Are You Sure? Yes/Cancel’ message.

Inline Confirm - Before

Inline Confirm - After

I really liked this as there was no page refresh for the confirmation message and it was not a modal popup, which is a little obtrusive at best. It also occurred to me that something like that would not require a huge amount of code either. This is what I came up with:

1
2
3
4
5
6
7
8
9
$.inlineconfirm = function(el, callback, parentSel) {
        var hideEl = parentSel ? $(el).parents(parentSel) : $(el);
        hideEl.hide()
        $('<div class="confirm">Are you sure? <a class="confirmyes" href="#">Yes</a> <span>|</span> <a class="confirmcancel" href="#">Cancel</a></div>')
            .find('a.confirmyes').click(function() { callback(); hideEl.show();  $(this).parents('div.confirm:first').remove(); return false; }).end()
            .find('a.confirmcancel').click(function() { hideEl.show(); $(this).parents('div.confirm:first').remove(); return false; }).end()
            .insertAfter(hideEl);
        return false;
    }

I decided on using just a function rather than a plugin, as I wanted asp.net control compatibility (see later). The function just swaps out the element(s) for the confirmation message and puts them back if cancel is pressed, otherwise it runs the callback. It utilises three parameters:

  • el – The element which initiates the inline confirm. i.e. The link
  • callback – A function to run if the answer is Yes
  • parentSel – (optional) This is a jquery selector that identifies a parent element of el that will be replaced with the prompt. This is so that you could for instance hide an entire section of html with the ‘are you sure?’ prompt. Particularly useful to keep layouts consistent.

This is a nice easy function to use in most web development language, however, if you are using asp.net, it becomes difficult to use it with the asp controls like <asp:Button /> or <asp:LinkButton />. This is because ASP.NET likes to take control of the click events of these so that it can create its event model at the server. There is the onClientClick property which allows us to have some control over the click event but we need to pass a callback function. After a little investigating, I discovered the GetPostBackEventReference function:

mylinkbutton.OnClientClick = "$.inlineconfirm(this,function() {" & ClientScript.GetPostBackEventReference(mylinkbutton, "") & ";});return false;"

The GetPostBackEventReference returns a string of the function that will be used to invoke the postback. Just what we needed.

Templating Your ASP.NET Pages

The majority of my ASP.NET development time is spent on web applications. Recently however, I was creating a marketing website to complement one of those applications and realised it required a slightly different approach to that which I was used to – we needed maximum changeability for as little downtime. Switching off the option to compile the pages into the dlls was the first step but I wanted pages with as little structural code in them as possible, as they may be edited by a non-developer. I discovered that the use of template user controls was the answer to this and meant that the pages would contain controls similar to this:

1
2
3
4
<uc:contentarea id="mycontent" runat="server">
  <headingcontent>Some Heading</headingcontent>
  <maincontent>Lorem ipsum..</maincontent>
</uc:contentarea>

In this way, any html code that affects the layout would be hidden away and anyone changing them cannot accidently break the layout. How does one do this? It is fairly straight forward. First you create a new user control and write the html as you want it, with the areas where the content is to be inserted marked to run at server:

1
2
3
4
<div id="mycontentcontrol">
  <h1 id="heading" runat="server"></h1>
  <p id="content" runat="server"></p>
</div>

The differences to a standard user control occur in the codebehind:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Imports System.ComponentModel
Partial Public Class MyControl
    Inherits System.Web.UI.UserControl
    Private _headingTemplate As ITemplate = Nothing
    Private _contentTemplate As ITemplate = Nothing
 
    Private Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        If Not (HeadingContent Is Nothing) Then
            Dim container As New ContentContainer()
            HeadingContent.InstantiateIn(container)
            heading.Controls.Add(container)
            heading.DataBind()
        End If
        If Not (MainContent Is Nothing) Then
            Dim container As New ContentContainer()
            MainContent.InstantiateIn(container)
            content.Controls.Add(container)
            content.DataBind()
        End If
    End Sub
 
    <TemplateContainer(GetType(ContentContainer)), _
       PersistenceMode(PersistenceMode.InnerProperty), _
       TemplateInstance(TemplateInstance.Single), _
       Browsable(False)> _
   Public Property HeadingContent() As ITemplate
        Get
            Return _headingTemplate
        End Get
        Set(ByVal value As ITemplate)
            _headingTemplate = value
        End Set
    End Property
 
    <TemplateContainer(GetType(ColumnContainer)), _
        PersistenceMode(PersistenceMode.InnerProperty), _
        TemplateInstance(TemplateInstance.Single), _
        Browsable(False)> _
    Public Property MainContent() As ITemplate
        Get
            Return _contentTemplate
        End Get
        Set(ByVal value As ITemplate)
            _contentTemplate = value
        End Set
    End Property
 
    Public Class ContentContainer
        Inherits Control
        Implements INamingContainer
 
        Friend Sub New()
        End Sub
    End Class
End Class

There is quite a lot here but it is fairly straight forward. The key to it is using the ITemplate interface for the properties that represent each of the areas you want as editable. This allows you to place the tags within the control in your page. At runtime , the content of these is placed into a control – the ContentContainer class, using the InstantiateIn method and that control is then placed into the html.