Friday, May 27, 2005

Ajax.NET

Ajax.NET is a really nice, easy to use library that should be able to help anyone get up to speed quickly with cross-browser compatible AJAX.

If you don't know what AJAX is, visit the link, there's a few nifty examples. The nice thing about Ajax.NET is that it supports Types not inheriting from Page. This is a big advantage since it means you can basically keep a very clean Controller design, and just plugin AJAX capable controls in place of traditional ones.

The hardest thing about a recent AJAX feature I toyed with for an application (an auto-complete TextBox, and yes I know there's free examples out there, I wanted the practice) was not using the library. I literally had that done in 15 minutes and that includes reading the docs. The hardest part was that I wanted the drop-down to be an iframe so I wouldn't have to worry about SelectBoxes with infinite z-index in IE. To do this took a lot of work. In the past I've used hidden iframes for communication, but the elements I was using to pass values were actually in the page already. I never had to generate/add elements (in an iframe) on the fly before. Add to that I couldn't use InnerText (FireFox doesn't support it), appendChild() (IE doesn't support it within an iframe), and IE & FF access iframe content differently and it was a tough nut to crack.

Still, in the end, the results came out very nicely, so it was worth it I suppose. Of course there are Controls you can buy that will do this for you. I think the bigger draw to AJAX is things like validation, authentication, postback-less editing, etc.

I messed with authentication a few minutes before work today, but it seems you can't call FormsAuthentication.Redirect... within an Ajax.NET method. Not sure why. Could possible be because there is no postback?

Edit: Got interrupted there. Ok, so anyways, my thoughts were a Redirect isn't really a force-update of the client's URL. It's a substitution in the HttpStream that the client is already recieving. So you can't Redirect from an AJAX call.

So what can I do? Well, I can just change the location with Javascript. As long as I have a valid FormsAuthentication ticket, then the new location target won't get bounced.

The down-side is this doesn't degrade gracefully. Ok... should I care? I mean really, ASP.Net depends on postbacks pretty heavily. Anything "cool" is going to require some Javascript support. Is there any need to support browsers that don't support Javascript? Is it an accessability issue? I think some things can be, like the auto-completion TextBox. A login though? I'm just substituting Microsoft's doPostBack() with my own logic. I don't see that as a problem. What do you think though?

My Job (Venting)

I work in an ASP Classic shop. No COM, Stored Procedures for everything, the Database is the answer to every problem because that's all my manager knows how to do.

The only vbScript classes are the ones I've written. Every page just gets a huge Functions include.

Formatting is done with custom string parsers that are flaky, and extremely slow. The story is the same for Validation. Where there is client/server-side validation that is, most places if the input is invalid it's just ignored. Instead of Regex, string parsing is handled with lots of copy/pasted nested ifs for left/right/mid statements and lots of string concatenation.

A hundred context switches on a page are pretty much standard practice.

Everything's abbreviated until it doesn't make sense. Default is abbreviated to "dflt", TimeZone is abbreviated to "timezn". The Databases have no constraints, no FK's, are denormalized to a rediculous level, the IndexTuningWizard has never been run, there are no traces, every "lookup" (semi-static data to join with) is in an EntityAttributeValue style table with 5 different Value columns. If we need to store more than the 80 characters a single Value column allows, we concatenate the columns. The Text datatype is never used, even on pages that display one large block of text. Instead the text is split on newlines during insert, and inserted as single lines of varchar(256) with a column for line numbers.

We spend days going through renaming all pages in a site to prefix a new magic number for new clients even though they are physically different websites. Actually magic numbers are the order of the day. Recently a manager forced one of our database developers to remove the identity designation from a column being used as a descriminator for organization type because he was concerned that when one was deleted, and a new one added, there would be missing numbers. Missing numbers. On a surrogate key!

We could supply TheDailyWTF with a years worth of posts.

I'd like to be all intellectual and say "the language doesn't matter", but come on. VBScript. The c# stuff that handles batch processing is both faster and more reliable than the DTS packages used for the rest. The ASP.Net site I recently worked on for a demo was better than any production site we have now in performance, maintenance, features, and looks, and it was delivered in less time than it takes to copy/paste/rename one of the existing sites to setup a new client. And that's using NHibernate 0.8.3, where Pre-fetching is broken, so when that's resolved the one or two pages that aren't "click-boom" will be. The Database is normalized, with no abbreviations, and no EntityAttributeValue tables. ConnectionStrings are managed by DPAPI instead of the joke that is "here's the connectionString to database-A in an XmlFile, use it to get the connectionString for database-B (which is usually just database-A) from a table in database-A".

How do you convince people who are most concerned with keeping the status-quo that there's a better way?

Saw it at CodeBetter


What Video Game Character Are You? I am a Light Cycle.I am a Light Cycle.


I drive fast, I turn fast, I do everything fast. I even breakfast. I tend to confuse people with my sudden changes of heart. Sometimes I even confuse myself, which tends to cause problems. What Video Game Character Are You?

Eronel.Common and UIBroker

I made a few small updates to the XmlActivator. I added some test benchmarks, and support for overriding an object's Type with a type description in the Xml. In other words you can now use Interfaces, or Abstracts in your objects and specify the concrete or derived type in the Xml.

The benchmarks aren't earth-shattering, and truly it's going to be very usage specific. The bigger the object graph, the larger the Xml, the more Members there are to set, the more Reference types you use over ValueTypes, the slower. I used the "Garage" test (a Garage class with a few members, one being a list of Vehicles) as the basis for the XmlActivator benchmark. It executed 10,000 times in 4 seconds on my Centrino1.5Ghz laptop. 2,500 objects per second then. Seems fair enough to me, though I'm sure with actual Profiling there's lots of room to improve on that.

Just to reinforce how usage specific the performance will be, I also benchmarked the RegexActivator using the "Pet" test as it's basis (a Pet class with some members, one being a Person as the owner). Even though the RegexActivator is just a wrapper for the XmlActivator with some Matching and extra string manipulation, 10,000 iterations with it took only 3 seconds.

On to the UIBroker... I need to add dot-notation (or underscore replacements) support to it. Right now you have to compromise your form design with extra containers just to map deeper in the graph. I'll need dot-notation anyways to add mapping-file support cleanly I think.

Nothin' much else new. Done a bit of AJAX recently. Really nice. Working in an ASP3/No-COM/Sproc-Everywhere shop still sucks. Badly. But hopefully with the delivery of an ASP.NET project I just worked on things will finally start to change.

Sunday, May 08, 2005

Eronel.Common 1.4

As promised, I just uploaded a new version of Eronel.Common to ProjectDistributor that includes a rewrite of the UIBroker.

Validator generation isn't supported. The old version's Attributes are done away with, with no replacement custom mappings as of yet. It is recursive on both the control tree side, and object graph side however.

1.4 also includes a tweak to Utility.ConvertStringToType() to support Types with no default constructor, but a constructor that accepts a single string as a parameter. (Such as Guid & Uri)

I need to get an ObjectView together for my latest work with NHibernate real quick, after that, I'll work on polishing up the UIBroker some more.

Saturday, May 07, 2005

UIBroker update...

Coming soon! Promise! Probably tommorow... I started work last week on the first web project I've worked on in about a year, and could've really used something like the UIBroker. So I'm gonna go ahead and re-write it. I'll keep the base class I think, but I'm probably going to kill the WinForms version until I get a quality implementation of the web-version. After that's done the WinForms version should be a piece of cake.

Since I've already re-written a good deal of it, and have a better idea of the direction I want it to go in, it should be pretty easy. I'm also going to do this one TDD style, like the XmlActivator was, since I'm pretty happy with how that turned out.

Definitely need to make this one recursive too. Lets lay it out real quick:

The whole point of this is to minimize tedious code. So I need to try to infer as much as possible. That means using the control-tree as the initial mapping, (after configuration-time mapping anyways), and walking it recursively. How do I handle mapping to an object graph recursively though? Can ID's have periods in them? Dunno off the top o' me head. If so, that's the way I'll go. If not, well, something else then.

I'll probably leave out validators in this version too. Tests, overall design, ease of use, and simple mappings are the focus of this version since that's what I have a need for right now. Performance, WinForms, and the last 5% of use-cases are on the back burner this release.

This page is powered by Blogger. Isn't yours?