11 Dec 2007

Callbackia - The land before Ajax

Okay maybe I'm wilfully ignorant but did you know that ASP.NET 2 had asynchronous client-server callbacks afore this AJAX lark began to make our lives so... rich and fulfilling? And from what I've used of them, they are a lot more practicable than the ginger stepchild Ajax.Net PageMethods that I covered previously.

So in essence, here's the gen.

1. Any Asp.Net Page or Control can expose itself to AJAX-style client-side calls and easily perform some server logic before returning some value or other.
2. You just have to implement the System.Web.UI.ICallbackEventHandler interface. This requires two methods, RaiseCallbackEvent(string eventArgument), which receives a request from client-side, and GetCallbackResult() which returns a string to the client.
3. You need to call a special client-script registration method in your ASP.NET code. This example explains it better than I can be bothered to:



string strClientCallbackAutoGubbins = Page.ClientScript.GetCallbackEventReference(this, "RequestArg", "ServerCallResponse", "OptionalContext", true);
string strClientCallbackFunctionCode = "function ServerCall(RequestArg, OptionalContext)" + "{ " + strClientCallbackAutoGubbins + ";}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ServerCall", strClientCallbackFunctionCode, true);


4. Then you just need to implement client script to call the ServerCall client function and get the response back in the
ServerCallResponse client function.

5. The format and purpose of the string argument passed to ServerCall, and the format of the response string returned to
ServerCallResponse is up to you. You could use JSON, XML or any other bloated WEB2.0ism of your choice - or you could do wot i dun and just pass a bog standard querystring along.

ViewState Mayhem

I made a portal app that had little draggable, dynamically loaded ASP.NET webcontrols that you could move around a dashboard. All was fine and dandy until I needed to handle control events in these draggable controls. See, when I moved a control, the viewstate got all munged up and controls started restoring each other's data. WHY WAS THIS SO?

Turns out that by default, ViewState is maintained NOT by an index of ClientIDs but by offset indexes to the parent control. So if you dynamically change the order of controls loaded in a container between first view and postback, ViewState will go boom.

The elusive, and not very satisfactory solution, is the mysterious ViewStateModeById custom attribute. When adorning a class, it ensures the object will have its ViewState keyed by ID instead of by index. Huzzah. Only prob is you need to wrap everything you want to maintain this way in a thin wrapper in order to implement the custom attribute. Oh joy.

Anyway for this and other sexy CustomAttributes you may have missed, check dis:

5 Jul 2007

Of ASP.NET Ajax PageMethods and Men

[11 Feb 2010] Since I wrote this, I would use the following method to call PageMethods from JavaScript: http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/





I've been having fun with ad-hoc AJAX calls using ASP.NET Ajax recently. And when I say fun, I mean in the sense of "no fun at all". Partly due to crap documentation and a million blog posts with example code based on obsolete beta Atlas functionality.

So here's a little tipfest about PageMethods.

You can call .NET methods of your ASPX page via client-side Javascript. But first you have to jump through some hoops:

1. The ASP.NET Ajax ScriptManager control in your .aspx or MasterPage needs to be set with: EnablePageMethods="true"

2. The .NET method you wish to expose to AJAX must be public and static and marked with the [System.Web.Services.WebMethod] attribute

Once that's done you can call your method from javascript after the AJAX script libraries have finished loading (with Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded() or something).

So, given a WebMethod like so:
[WebMethod]
public static string HelloWorld()
{
return "Hello World!";
}
You call it in JavaScript with:
PageMethods.HelloWorld(MyCallbackHandler);
And natch you have to provide that callback handler function e.g.
function MyCallbackHandler(Result)
{
alert(Result);
}
That's right my friends, the PageMethod takes the original argument list, plus one extra for the mandatory callback function, and then there are some optional extra callback arguments you can provide regarding error handling etc. Check out the docs for more info.

One extra thing to note - I read a few blogs bitching that the WebMethod had to be declared in the .aspx page, not the code-behind code. That's not true anymore, it works fine both ways.

15 Jun 2007

ScottGu Snogging Time

1.5 days banging my head against a brick wall - ViewState not being loaded for dynamically added controls. ScottGu sorted it out:

http://scottonwriting.net/sowblog/posts/2129.aspx

16 Apr 2007

GridView Row-Click

A simple way to add "select on row-click" functionality to GridView without causing Event validation errors:


protected override void OnRowCreated(GridViewRowEventArgs e)
{
base.OnRowCreated(e);

if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onClick"] = "this.style.cursor = 'wait';"
+ Page.ClientScript.GetPostBackEventReference(this, "Select$" + e.Row.RowIndex.ToString(), true);
}
}


And how do you handle the click? Just hook up to the GridView's SelectedIndexChanged event handler and check the GridView.SelectedValue property.

ps. for row-hover and striping fun, why not use JQuery? Just implement the grid's RowStyle.CssClass (e.g. set it as 'zootGridRow') and set some style directives to handle the following classes...


$(function() {

// Implement grid-row striping
$('#myGrid .zootGridRow:odd').addClass('zootGridAlternateRow');

// Implement grid-row hover animation
$('#myGrid .zootGridRow').hover(function(){$(this).addClass('zootGridRowHover')},
function(){$(this).removeClass('zootGridRowHover')});

});

9 Apr 2007

Roman Holiday

Sarah and I went to Rome for Easter 2007 - Friday to Monday. Wow! What a city. We saw loads of amazing stuff that really blew our minds. We think we have archaeological history in Britain - but in Rome it's still standing! Amazing.

Anyway, click this post's title if u wanna see pics.

Just want to give mad props to the hotel we stayed at: The Mecenate Palace. This is conveniently located within suitcase-dragging distance from Termini train station, and is just off the Plaza di Santa Maria Maggiore - which the terrace roof garden overlooks for breakfast. We booked in there via Last Minute and managed to get a lovely Executive Floor room - all wood floors and a jacuzzi bath. Really good.

Oh and boooo to the Restaurant Diocleziano on the Via Viminale, where we had crappy italian food on the first night, which I didn't think was possible!

6 Feb 2007

What I Done For Christmas

  • I done broke my arm
  • I done crashed my motorbike*
  • I done quit my job for no apparent reason

Life is so weird to begin with, and then suddenly it gets weirder without warning. You think that surely some fundamental law of the universe will stop you from stepping further out of the boundary, but no! It's not necessarily good out there - and I don't advise you all to go, but it is different.

* Okay can I cast some advice out to the ether in the forlorn hope that it'll save someone's bacon and/or dosh.

  1. Get some sticky all-weather tyres for your bike. No arguments.
  2. Comprehensive insurance is SHITLOADS cheaper than fixing your knackered bike. Try a grand cheaper. Just do it.
If I helped you out today, you can buy me a beer below. Cheers!