Welcome to CrankyGoblin.Com Sign in | Join | Help

Public Class GeoffAppleby

Inherits Microsoft.VisualBasic.MVP : Implements IBrainFart
Custom postbacks in ASP.net

First, is it just me, or are the standard .net blogs fairly low on the asp.net? By standard, i mean the big five (that i read, anyway) - dotnetjunkies, blogs.msdn.com, weblogs.asp.net, geekswithblogs and vbcity. Yes, i know msdn and weblogs.asp.net are the same thing, but think of them differently. I only read weblogs.asp.net via the 'non microsoft staff' link, so it's two sets of posts :)

Anyway, on all these there's a lot of nice geeky stuff. Many different products, a lot of .net framework talk, general code tips, a fair bit of winforms, but hardly any ASP.net stuff.

ASP.net is one of my two biggest unknowns in .net. General framework stuff, i think i'm pretty good. Same with winforms in general. I prefer to write class libraries and stuff, the business layer in the n-tier world. I deal with a fair bit of web service stuff, but i'm nowhere near an expert, and I haven't had much of a chance yet to look into all the WS-extensions that many people keep talking about (I consider my level of understanding to be roughly WS-wtf).

ASP.net is my biggest unknown. The whole thing is different to what i'm used to. HTML is HTML, code is code, and never the twain shall meet, that's what i always thought. The whole page lifecycle, the event model, it's always been very alien, and i've never had a real excuse to fully work it all out. And viewstate? It always seemed (and still seems) like pure evil to me. I've seen viewstate strings (you know, the hidden form element on the page) that are huge. It's all well and good talking to local web servers on a decent lan connection, but what about poor modem users? Ok, rant on that bit over :)

So i thought i'd put a tip out there in the blogosphere. It's a hack, and it's a bad one. Nothing I'm doing here is really that good, but it works for me, and for those of you in a similar bind, it might work for you too. I provide no warranties, nor do I expect it work after an upgrade to whidbey.

For the last couple of weeks i've been thrown right in the deep end (I mentioned it in a previous post) working on a web custom control that completely emulates the winforms property grid (How's it going? I hear you ask. Awesomely). Getting this thing sorted out has taught me a hell of a lot about how this whole asp.net thing works. I'm sure i've got a lot wrong (or at least, misguided - better solutions to some of the stuff i've done is bound to be apparent for those of you have more of a clue in this world) but it's kicking ass and looking fantastic, and runs at a decent speed too.

Today I worked something out (with help from my ole trusty partner-in-code) that i thought was pretty cool.

The only things that have server events are those things that cause post back (this is how my understanding works). A postback is getting some server event to fire (some control event, generally). But what happens when you don't actually have a control, but need a postback?

This is fairly easy. And i managed to take it a step further to suit my own needs, but i'm probalby breaking a million and one rules :)

To start with, you need your control to implement IPostBackEventHandler.

     1: Imports System.ComponentModel
     2: Imports System.Web.UI
     3:  
     4: Public Class Class1
     5:     Inherits System.Web.UI.WebControls.WebControl
     6:     Implements IPostBackEventHandler
     7:  
     8:     Public Sub RaisePostBackEvent(ByVal eventArgument As String) _
     9:      Implements System.Web.UI.IPostBackEventHandler.RaisePostBackEvent
    10:  
    11:     End Sub
    12: End Class

The RaisePostBackEvent() event is used to catch your arbitrary postbacks. The eventargument parameter is a string in which you can stuff information that you might need. From here, you can process your postback, and everything is good.

How do you get the postback invoked? Here's the basic way which the msdn doco says to do it (let's use a server side span as an example):

    13:     Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    14:         Dim sMyID As String = "specialSPANTag"
    15:         writer.WriteBeginTag("SPAN")
    16:         writer.WriteAttribute("id", sMyID)
    17:         writer.WriteAttribute("onclick", Page.GetPostBackClientEvent(me, "this is the argument to the postback event"))
    18:         writer.Write(HtmlTextWriter.TagRightChar)
    19:         writer.Write("Click me")
    20:         writer.WriteEndTag("SPAN")
    21:     End Sub

So now the click event of the span is set to post back "this is the argument to the postback event" to the event handler.

But now I have some trouble. You see, the way the property grid works is that there's a fair bit of client-side script already, such that depending on what line of the grid you've clicked on, there might be some dynamically created links shown at the bottom of the grid. This means that don't have any code running on the server at the time outputting the onclick handler with the call to the Page.

So i did some tests. The actual HTML that's output for the above span comes out like this:

<span id='specialSPANTag' onclick='__dopostback('Class1', 'this is the argument to the postback event')'>Click me</span>

Ah-ha, says I, now i'm sorted. So my link gets cunningly crafted to look like this:

<a id='speciallink' href='#' onclick='__dopostback('propertygrid', 'speciallink')'>link text</a>

So what now? Javascript error in IE. It ended up that the trick here is that the actual source for the script function __dopostback() is written out by ASP.net only if you make the call to Page.GetPostBackClientEvent().

My solution was equivalent to the following:

    13:     Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
    14:         Dim sTemp As String = Page.GetPostBackClientEvent(Me, Nothing)
    15:         'rest of render code went here. Throw sTemp away.
    16:     End Sub

As I said, I'm sure there's a lot of rules being broken. But it works. Now when the page is rendered, the content of the __dopostback() function is written out too. Yay.

Listening to: these days - powderfinger - (5:00)
Posted: Wednesday, October 27, 2004 9:30 PM by Geoff Appleby

Comments

Steve said:

Nice post and walkthough on how you got there. I hadn't thought about the lack of ASP.NET and looked at my own blog to see if I was posting ASP.NET bits. I really haven't even though I've been working primarily in ASP.NET for the past 3 years. While I develop similar hookups using javascript all the time, I don't find that code 'interesting'.
# October 27, 2004 10:36 PM

Steve said:

Just hit submit and didn't mean to... I think there is stuff in ASP.net that I've done that would make for interesting posts, but I tend to think of those solutions as browser workarounds rather than cool coding. I like the way you layed out the code and explained it. I'm looking at an entry I wrote about using GDI+ graphics in our ASP.NET app (a workaround compared to fat-client) and blogging the actual code the way you did. Nice job.
# October 27, 2004 10:40 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

To submit your comment, click on these pictures:
  • Super Geoff!
  • Geoff's mother on a booger hunt
  • Geoff's pretty blue eyes
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Can't recognise the people in these pictures? Look here for a quick introduction.
There's a time limit for you to get your comment submitted before this set of pictures expires. If you think it's been longer than 10 minutes, get some new pictures first (you won't lose what you've typed so far).
Get some new pictures 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS