Welcome to MSDN Blogs Sign in | Join | Help

Castle ActiveRecord

Lately, I’ve been playing around with Castle ActiveRecord tolearn about this particular technology. For those of you who are unaware, Castle ActiveRecord is an open sourceimplementation of the ActiveRecord pattern written in .NET and built onNHibernate.

The ActiveRecord pattern represents rows in a table asinstances of a class (with column values as instance methods) while providingaccess to the table itself as static methods of the class.

For example, a database table named Users might berepresented by a class called User. The User class would have a static method called FindRow which takes ina numeric value corresponding to the primary key of that table.  User.FindRow(5) would return aninstance of a User object, which would have various properties such as Name.

The benefit of this is it allows developers to access andmanipulate data in a database while providing a layer of abstraction from theactual database syntax.  This codecan be database agnostic and hide the user from SQL queries and what not.  It also allows simplifying databasecode and being able to perform basic database operations in one or two lines ofcode.

One of the benefits of Castle ActiveRecord is you can defineyour entire database schema using .NET code and even have the engine create thedatabase for you.  For example, tocreate a User table, we could use the following code:

 

 

[ActiveRecord(“Users”)]

public class User : ActiveRecordBase<User>

{

string name;

[Property(NotNull = true)]

public string Name {get {return name;} set {name = value;}}

}

 

 

Using various attributes, you can specify database typemappings, primary keys, foreign constraints, indexes, etc.  When you’re done, you can instructActiveRecord to create the database using a given connection string.

We can now create a row in this table with the followingcode:

User user = new User();

user.Name = “Mike”;

user.Create();

 

This eliminates the need to use ADO.NET or construct SQLstatements or stored procedure calls.

One interesting thing you can do is specify the relationsbetween tables.  If I had an Ordertable, I can specify a User that placed the order:

 

Public class Order

{

….

 

[BelongsTo(“Name”, NotNull = true)]

public User PlacedBy {get {return _placedby;}}

 

You’ll notice this method actually returns a User object, notjust an int or a guid or what not. When an Order row is queried, Castle ActiveRecord joins in the Userstable and also populates the PlacedBy instance of the order.  You can enable a feature called “lazyloading” which will not query the Users table until the property getter isaccessed.  This would prevent thegeneration of queries with lots of joins.

So far, I’ve found Castle ActiveRecord to do a great jobhandling simple database operations for me, however it definitely has itsdrawbacks.  I’ve found it lackingin creating any sort of complicated database schema, as it doesn’t seem to beable to create indexes on foreign keys or allow the user to specify clusteredvs non-clustered indexes.  However,it can also generate a SQL script to create your database and output to a fileso you can make changes before provisioning your database.  For more complicated scenarios, I wouldnot use Castle ActiveRecord for database provisioning.

There were a few instances where I wanted to be able toreturn only certain columns from the database and control exactly what tablesget join’ed in.  It seems CastleActiveRecord wants to return all columns all the time, or no columns and generate new SELECTstatements every time you access a property.  It would be nice if we could simply specify what columns wewant to query for, and the remaining properties would remain null.  For these scenarios, CastleActiveRecord can create an IDbCommand and you can fire off your own storedprocedure or SQL statement.  I’vefound using a mix of regular ADO.NET and ActiveRecord calls for the simplerstuff is a great approach for more complicated applications.  The ActiveRecord base class also allows you to override various methods, and pretty much any part of the system can be rewritten.

One thing that has disappointed me is it seems support fortransactions is completely broken! I can create a transaction like so:

 

using(TransactionScope t = new TransactionScope())

{

//Do some DB calls

t.VoteCommit();

 

}

 

In theory, if the code crashes, the transaction will neverbe committed and the Dispose method of TransactionScope will roll thetransaction back.  However, when Itried this, I found the SQL code isn’t getting run and no SQL errors would begenerated until the Transaction is disposed, thus making it impossible to rollback the transaction due to database errors.  On thesupport forums, I found several other people who ran into this problem but noone had a solution for it yet.

Overall, I think this technology is a great model for dataaccess using .NET applications and works perfectly for web applications aswell.  It seems they need to ironout a few minor problems, but they have a large following and an active supportcommunity.  It’s also open sourcewith a very flexible license, which would allow large applications to run ontheir own customized version of Castle ActiveRecord.  I think the pattern is very solid and at the very least,should give you some ideas for creating a database access layer from scratch for yourweb based applications.  I’d bevery interested in hearing from anyone using Castle ActiveRecord in theirapplications and what they like and don’t like about it.

For more information, visit: http://www.castleproject.org/activerecord/index.html

Mike

Posted by mikechr | 3 Comments

Lowes

I don't really know why I bother buying anything from Lowes anymore.  They don't actually install anything they sell.  First, I buy a new Bosch tankless water heater.  I did all the research online and found the exact unit I wanted, and Lowes had the best price.  I purchase the unit and take it home.  First, I call the water heater people who I've worked with before to ask if they'll install it.  Of course not, they will only install a unit if you buy it from them.  I call several other companies and get the same story from them.  So I call Lowes back and ask them to please install the water heater they sold me.  After being transferred about 900 times, I finally reach the plumbing dept.  The guy says he'll find out if they can install it and call me back.  A few minutes later I get a call back, and he says no, they won't install tankless water heaters and no, he doesn't know anyone who will.  Mind you, on Lowes.com every page has links to "find out about in-home installation on this product".  Why does Lowes sell a product they don't even install, or even know anyone who will install?  Next, I try ServiceMagic.com - they'll find people to do anything.  Within minutes, I have a plumber who says he'll install it and he'll be at my house in 30 minutes.  I leave work early and head out to meet him.  He looks at the unit like a cat looking at a UFO.  He has to call several of his plumber friends to ask what type of venting he needs and how to install this thing.  About 45 minutes later, after telling me how much he doesn't like the unit I bought, he gives me a quote for $1600 to install it.  Mind you, the first company I called wanted $1800 for the unit and installation, and it was a way better unit than the one I bought.  So the thing went back to the store, at least Lowes does refunds.

Next, I buy a Fisher & Paykel drawer dishwasher from them.  They charge me $129 for installation.  A few days later, I get a call from their installers asking me questions such as why type of pressure release valve I have and if I have a GFCI outlet.  They claim there will be all sorts of additional charges if they need to install a new outlet and they usually do a pre-inspection before installing these dishwashers.  The dishwasher shows up today and the installer, as he's into the kitchen, says, "No, this won't work."  These units don't work with a Johnson T-valve and none of the existing plumbing will work.  Will they fix it?  No, they don't do that work - I have to hire a plumber.  If I'm going to hire a plumber, he might as well do the installation as well.  He says these dishwashers basically don't work with any standard plumbing and it has to be setup in advance to handle this dishwasher.  So basically Lowes will install the dishwasher for $129 if for some ungodly reason your dishwasher hookups are exactly what's required.  I can now see why Fisher & Paykel has a $129 installation rebate on their dishwasher, because they know no installer in this solar system is going to install it for that price, and the only people who will buy it are people who completely gutted their kitchen and are redoing all the plumbing, and those people already have a plumber anyway.

Sigh.

Mike

Posted by mikechr | 0 Comments

Writing a simple managed control under IE

Most web developers are aware of various "controls" and "applets" that can be "hosted" by "Internet Explorer" (hmm, not sure why I quoted that last thing, I guess I was on a "roll".)  This code is compiled code that runs within the IE process and draws itself within the boundaries of the document.  The control even has access to the outside container.  This is useful for doing all sorts of nifty stuff that might be hard to do using pure script or HTML, such as drawing graphs, animation, creating an interactive grid, creating a chat room, etc.  Most of these controls are written in Java or COM (ActiveX).  Java requires a special runtime that you have to download, and ActiveX requires your users to be running one of the many ActiveX compatible web browsers (There's tons!  IE3..  Umm, IE4..  IE5..  Oh yea, IE5.5..  IE6, just to name a few)..  However, what if you really want to keep users away from your site and write a control that requires them to download a special runtime ANNNNND only be able to use one browser.  Well, then my friend you definitely need to write your own managed controls.

 Only a hand full of web developers are aware that IE (recent versions, not sure which ones) can run managed code.  Even less than a hand full (maybe a paw of a very small cat?) can actually tell you how to do this.  Provided your users have the .NET framework installed (who doesn't?) there's a special syntax of the <object> tag that can instantiate a managed Winforms control.  I found information on the Internet a little sparse on this subject so I decided to write a post describing exactly how to do this.  Not that you should, as I'm sure I'll get 32,768 comments telling me that my apps are crap, proprietary and how that mentality somehow mirrors the exact attitude of Microsoft as a whole.  Well, let me tell you something.  This blog is dedicated to building web based applications, not web pages.  Applications run on a certain platform.  That platform might be Windows, that platform might be Mac, that platform might be the Java runtime.  It might be a Commodore PET, a cell phone, a Zune, one of those old TI-85 graphing calculators, whatever.  This platform can also be Internet Explorer.  In fact, one of the reasons IE became so much more popular (especially within corporate networks) over say, Netscape, is it's an actual web application platform - not just a browser.  Authors of applications can write applications for whatever platform they choose, based on its requirements as well as the users of said application.  I might write an IE specific application for setting up direct deposit because my IT department has rolled out IE to everyone in my company.  It's cost effective to target a single platform.  There exists a certain spectrum; on one side you can scale to many different types of users but your development/test costs go way up and/or your feature set goes way down.  On the other side, you can write a program once for a certain platform and  target a very specific set of users.  It's up to developers to figure out the best spot in that spectrum for their specific application.  So enough of my rant, let's get back to the subject.

First, let's create a managed DLL with a single class in it.  Since I don't feel like writing a full fledged control, all this thing will do is pop up a message box.  Or maybe I don't actually know how to program and this whole blog's a lie.  However, you'll get the point - you can add more controls to the child controls collection, override all sorts of events, etc.


[assembly:System.Security.
AllowPartiallyTrustedCallersAttribute]
namespace
HostedControlTest {
   public class TestControl : Control
   {
      public TestControl()
      {
         MessageBox.Show(
"Hello World!");
      }
   }
}

Compile the DLL, upload it to your web server in a location that clients have access to reach.  You can test this by typing in the URL for the DLL and make sure the IE "Save" dialog comes up and you can download your own DLL.  You might have certain web server security restrictions (especially if it's a Sharepoint server) that prevent users from downloading DLL files.  It doesn't matter what web server you're using, it doesn't matter if the web server knows anything about .NET.  It's simply a binary file sitting up on a server somewhere and it's downloaded exactly how, say, a JPG file is downloaded.  Also, I'm pretty sure you can even use another extension other than DLL.

Once you have this working, create a new web page.  On the page, place an object tag that looks something like:

<OBJECT classid="HostedControlTest.dll#HostedControlTest.TestControl">

You can replace HostedControlTest.dll with any valid relative path to your DLL.  After the pound sign (or, octothorpe as I like to say) is the class within the DLL to load.  Note I fully qualify the path with the namespace as well.

Load up your page through your web browser and the control should run and you should get a popup on your screen.  No need to sign anything, no need to click "Yes" to any security warnings, etc.  In fact, all security is taken care of for you by Code Access Security and is enforced by the runtime's security policy on your machine.  Your control can request permissions (such as local file access) and it's up to the client's machine what it trusts the control to do.  If a control all of a sudden tries to do something evil, the runtime will throw an exception.

That's all there is to it.  Don't ask me any questions because this is all I know!  Seriously.  Actually, feel free to ask me questions and I'm sure I can find out the answers for you.  Thanks!

Mike (Web Dev Guy)

Housing prices

When I moved to the Seattle area over eight years ago, I knew I wanted to make this place my home.  Since it was clear my residence would be permanent, it seemed like a good idea to buy something rather than rent.  Back then, I found a nice condo for around $130,000 in the Redmond area.  At a decent interest rate, a 30 year fixed rate mortgage with a 20% down payment was about $680/month.  It was a no brainer!  I was paying almost $900/month for an apartment, and had I not moved they were increasing my rent to $1090.  I could have a bigger place for cheaper, and build equity I could later use as a down payment on a house.  I also owned the inside walls and could do stuff like remodel the kitchen, paint, install hardwood floors, etc.  Back then, the only reasons most people continued to rent were 1) they didn’t plan on being in the area very long or 2) they had lots of debt or credit problems preventing them from getting a home loan.

Now days, it’s much different.  My condo is worth about $240,000 and it’s considered a pretty low end place.  Most of the condos in the Kirkland area are $300k-$400k, and if you want down town Seattle you’ll pay even more.  With interest rates starting to climb back up, it’s harder to justify paying $2,000/month or more for a condo.  Gone are the days of using a condo as a “stepping stone” between an apartment and a house.  The concept of “owning is cheaper than renting” is gone, which scares away most people – especially those who aren’t too concerned about their financial future.

It seems the solution to this over the past couple years has been to keep lowing the interest rates until people can afford houses.  But has this just made the problem worse?  Most people look at a house in terms of what it costs them per month.  I have x dollars per month that I can afford as a house payment.  What does this buy me?  As interest rates drop, the value of the house that money can buy me goes up.  This increases the buying power of the average potential home owner.  With so many people moving into the area over the past few years and more buyers than sellers, this allows people to offer more money on a house and causes the market value of houses to go up.  We’ve been seeing this for a few years now, and other states like California and New York are also no stranger to this.  When the point comes where people are having a hard time affording a house, banks do stuff they’ve never done before.  We have 40 and 50 year mortgages now.  We have 1-year adjustable rate mortgages.  We have interest only loans.  Banks do whatever it takes to lower your monthly payments to attract your business, all while housing prices continue to increase.

Those who cannot afford to buy a home have to rent.  Land lords have to raise rents to afford their mortgages, so rents are going up as well preventing people from saving any money.  In San Diego, a lot of apartment owners are getting the idea to turn their cheap apartments into low cost condos.  By low cost, I mean only $400,000 or so.  This lowers the availability of apartments thus driving the cost of other rental units up as well.  This ends up pushing poorer people out of the area.

So what’s the effect?  Those who can get their foot into to the real estate market continue to get richer while those who are forced to rent get further and further behind.  Is this creating a wider social gap between the rich and the middle class?  What can be done about this?  Obviously, raising interest rates would be a problem.  You don’t want the house you bought a year ago for $500k to all of a sudden only fetch you $300k because none of the potential buyers can afford that mortgage.  Is this simply capitalism at work and a normal aspect of our economy, or do all Americans have the right to be able to afford a house some day?

I was very lucky to “get in” to the housing game before all this non-sense started, and due to the appreciation of my condo I was able to make a nice 20% down payment on a home and have some extra money left over to invest.  I think I made a good decision to buy something seven years ago, but what about those who are just starting their lives now?  Some people push themselves to their financial limits to buy the cheapest possible shack and become “house poor”.  Yes, they have their house but they have to live off dry noodles every night for dinner.

I was talking to a real estate agent friend of mine and she said the majority of her clients buying their first homesare getting the down payments from their parents, or a family member.  Does this lead to a world where social status is inherited?

I’m very interested in any comments you guys have.

Mike

Posted by mikechr | 2 Comments
Filed under:

Housing adventures

I must apologize for my recent lack of blogging, but I’ve been most busy attempting to become a home owner.  This is a dream I’ve had for years now, but it was put on hold for a few years due to the most rediculous litigation surrounding my condo assocation.  One day, the association realized they were in $9 million dollars in debt and this was a problem.   Due to this unfortunate financial circumstance, my monthly home owners dues went from $117 to $330.  Since the corporate charter said they could not increase the dues by more than 10% a year, they were immediately sued by all sorts of people.  The prices of the condos in this complex plummeted and I was forced to stay unless I wanted to take a $20,000 loss.  After a few years, the association eventually won all the lawsuits (really good lawyers?) and the prices are finally starting to get back up to the same level as other similar condos in the area.

I decided to resume my dream of owning a house, however I became very interested in building it myself.  That way, I could get it just the way I wanted and use high quality materials.   I wanted something small and nice which is hard to find.  So I started looking into building a house – the first step is, of course, to find land.

Now, there’s a difference between a piece of land and a “lot”.  Land is simply any piece of dirt someone is willing to sell you.  This land might be on a slope, covered with brush, or be in some way totally unable to support any type of construction.   Of course, you don’t know until you actually do a feasibility study, which could costs thousands.  Lots would already be prepped and ready to build on.  A lot is tough to find unless you want a microscopic little tenth of an acre parsel in the middle of some yuppyville housing community.  Land around here goes for around $120,000 for anything decent.  Figure another $80,000 for leveling, escavation, clearing, permits, environmental studies, bribing public officials, etc.  So I figured I’d be looking at $200k before I could even start building anything.  So I called about 6 real estate agents looking for someone who would help me buy land.  None of them returned my phone calls.  It seems about 60% of land deals fall through and no one wants to get in that business.  In fact, the only people that build houses anymore are insanely rich people or major housing development corporations who build .1 acre lot yuppyville homes with the cheapest materials and give you a list of about 3 options to choose from.  This is not my thing.  So once you have the land, then what?  Well, you can buy a manufactured home.  This is by far the cheapest way to go.  You get these homes from companies such as Hiline Homes (www.hilinehomes.com) and they show up one day on the back of a rather large truck.  Those go for about $100k for a decent one, mind you they have incredibly undesirable floor plans.  If you want something nicer, you can go with a cute little log home from someone like Lindal Cedar Homes (www.lindal.com).  I love these!  These things show up on another rather large truck in pieces and you hire someone to put them together for you.  The cost is around $110/sf.  So figure $200,000 for a good size home.  However, this is just the outer “shell” of a house.  The walls, ceilings, doors, little metal bracket thingies, etc.  Once you’re done with that you’d have to hire a general contractor to fill in the innards which might cost you another $100k.  Third option - if you really want something nice, you have to hire an architect to design you something from scratch and have it custom built.  Custom built houses in this area go for around $300/sf.  So figure a nice little 2,000sf home would run you $600,000 just for construction.  Adding up these numbers makes building a house really push the budget of any average person.  So I decided to give up on this and look for an existing house that I liked.  One problem, I wanted a basement.

Why a basement?  Well, where else are you gonna hide all the dead bodies?  Actually, being a movie buff I really want to build a home theater.  It’d be great to have a projector mounted on the ceiling, with a nice 100” screen, accoustic tile on the ceilings, carpetted walls all in a room you could get pitch black.  Since it’s underground, you wouldn’t have to worry too much about noise.   And also as a guitar player – well you get the point.

Here’s the problem with that idea.  All the basements around here are daylight basements in Kirkland (not to knock on Kirkland, it’s a fine city but split entry houses are sooooo 70s.)  A daylight basement really doesn’t adapt well to my dream of having a home theater where I can crank up “The Mummy” and not have to worry about neighboring mobs showing up on my porch wielding pitch forks.  After looking at dozens of crappy houses, I decided to scrap the idea of having a basement (maybe someday) and start to look out east of Redmond.  Out there, you can still get a good amount of land and a decent place without having to give up your first born son.

My new house!Eventually, I found a great house on a big lot that I absolutely loved.  It has an awesome kitchen, great back yard for parties, plenty of space and a living room wired for home theater stuff.  I’ll be moving in next weekend if all goes well, and fixing up my condo to put it on the market before the holiday season.

One thing about looking for homes is it really helps you figure out what you like and what you don’t like in a house.  Walking through houses I absolutely hated was a great exercise and a most valuable experience.  I started to get really good at narrowing down what kind of house I wanted and what features were the most important, and I eventually found out that having a basement was not as huge of a requirement as I previously thought and wasn’t worth sacrificing other characteristics I wanted.  Having a big lot and a house that didn’t look like everything else on the street was far more important in the end.  One thing I did was take pictures of every house I visited and started to compile notes on what I liked and what I didn’t like.  In somewhat of a "binary search" fassion, I was able to narrow down exactly what I wanted in a house.

Hopefully when the dust settles, I’ll be able to blog more again.  Stay tuned for my semi-left wing rant on housing prices (I didn’t want to make this entry too long).  That’s it for now!

Mike

Posted by mikechr | 33 Comments
Filed under:

Yay! Higher gas prices!

Now that I've caught your attention with my post title, let me explain.  Unlike most people, I'm a fan of high gas prices.  I'm sure there's a point where I'd start walking to work, but the extra 50 cents per gallon costs me maybe $20 dollars per month.  It's $20 dollars I could use for other stuff perhaps, but it's not the end of the world and it's not nearly as bad as the thousands I spend on a poorly managed social security program.  Now, there are of course the people who 1) fill up their tanks more than I do and spend much more than $20 dollars extra per month, or 2) the people who are working their butts off to barely make ends meet.  And, of course, gas prices affect the price of a lot of other stuff.  This is painful, but I maintain that gas is simply not a requirement to survive (unlike water and oxygen.)  There will come a point where Americans simply won't agree to pay for it anymore - which brings me to my argument.

Though it's unfortunate, we happen to live in a country that doesn't do anything about a problem until it actually becomes a problem.  Now I don't like it, but that's the mentality we have as a people.  So, these high gas prices have started to really make a difference in the priorities of consumers.  People are looking for more gas efficient vehicles, which creates demand, which creates a market.  Various car companies are spending lots more money on Hybrid technologies, which keep getting better and better.  More money is being spent on alternative fuel sources such as this cool little vehicle:

http://www.teslamotors.com/

It's a fully electric car that does 0-60 in 4 seconds and can drive 250 miles on a full charge.  It can't replace my current car yet, as I like being able to do long road trips, but this is a huge breakthrough on previous electric cars that had a range of about 60 miles.  Hopefully this sort of innovation will result in a huge breakthrough in energy storage (better laptop batteries, cell phone batteries, etc.)  There will some day be a car that's cheap, does not run off gas, is quick and easy to "recharge", and drives like a Viper - and higher gas prices is going to drive that sort of innovation.  It's either that or we wait until we run out of oil completely.

So bring on the high gas prices, it hurts now but if it results in a better world I'm all for that.

Mike

Posted by mikechr | 3 Comments
Filed under:

JScript Functions

My favorite IE tip/trick of the day has to do with function pointers and anonymous functions.

 

In Jscript, there are two keywords for creating functions.  One is “function” with a lower case “f”, and one is “Function” with an upper case “F”.  “function” is a keyword that allows you to describe a function in-line.  The “function” keyword creates a named function (even if you don’t specify a name) and returns a pointer to that function.  In most cases, you simply ignore the return value:

 

function Foo()

{

   window.alert(“Hi!”);

}

 

is an example of this usage.  However, I can also say:

 

var myFuncPtr = Foo;

myFuncPtr();

 

To call my function as well.  Or, I can do:

 

var myFunc = function test(s)

{

   window.alert(s);

}

 

To create a named function called “test” and create a variable called myFunc which holds a pointer to that function.  I can then say:

 

myFunc(‘Hello’);

 

To print ‘Hello’ out to the screen.

 

I can also say:

 

var x = function()

{

   window.alert('hello');

}

 

And have a pointer to a function with no name.  In similar pointlessness, I can do:

 

function()

{

   window.alert('hello');

}

 

Which is perfectly valid but it does absolutely nothing!

 

There’s also “Function” with a capitol F which is basically a built-in Jscript function that returns a reference to a new anonymous function.  An anonymous function is simply a function that does not have a name and walks the lands doing good deeds for strangers in need, while searching for its true identity.  Since it has no name, it must be called through a function pointer.

 

For example:

 

var items = {};

items[0] = new Function("window.alert('A');");

items[1] = new Function("window.alert('B');");

items[2] = new Function("window.alert('C');");

 

items[1]();

 

This allows me to create an array of anonymous functions that do different things, then call one of them through a pointer to that function.

 

In Jscript, functions are objects just like any object object.  These objects can have names, can be part of arrays, can be passed to other functions, etc.  The only difference is there’s special syntax (the parenthesis at the end) which directs the runtime to call the function rather than return a pointer to it.

 

So how about IE event handlers?  Many people take IE’s eventing model for granted, it just works.  But taking it apart is somewhat of an educational experience.

 

Let’s take this simple chunk of HTML for example:

 

<div id="myDiv" onclick="window.alert('foo');">Click Here</div>

 

It’s simple enough, but what is IE building in memory?  There’s a <div> object with an ID property which is a string, and there’s an onclick property with some script.  How does this script get compiled?  It’s an anonymous function, right?.  No!   It’s a function that’s called “anonymous” (how @#!$’ing confusing is that?!?!).  IE news up the function in its own compilation scope and returns it through a dispatch pointer.

 

The onclick property of our div object above is a pointer to a function (If you’re a COM guy I believe it’s technically an IConnectionPoint but who cares?)

 

You don’t believe me?  Let’s run this little piece of code:

 

window.alert(myDiv.onclick);

 

Which will print out:

 

function anonymous()

{

window.alert(‘foo’);

}

 

Interesting, eh?  If we want to call our function through our function pointer, we can simply do:

 

myDiv.onclick();

 

Which will run the code and display “foo”.

 

Ok so this is all silly and confusing, and for the people who actually understand all this, they are 1) the people who read this whole article and learned nothing they didn’t already know or 2) the people who are gonna leave me comments saying how something I said wasn’t quite accurate.  Well, sorry I’m an Office developer and knowing how the scripting engines work is just a part time hobby.  Thanks for reading, and hopefully you can use function pointers and anonymous functions to change the world for the better (the cure cancer anonymous function maybe?)

 

Mike

 

Posted by mikechr | 2 Comments
Filed under:

Great ASP.NET site

Here’s a great site for developers that aggregates a bunch of other ASP.NET blogs, making it easy to find new information all on a single site.  Check it out!

 

http://www.dotnetslackers.com/

 

Posted by mikechr | 0 Comments
Filed under: ,

IE Tips and Tricks - Part 1

It has occurred to me that I haven’t written much about client-side development and all that fun web browsery stuff.  Before I get branded a server only guy, I’ve decided to write an n part series (where n is the number of articles I can write before getting bored of the subject) about my favorite HTML/CSS/Script tips and tricks.

 

The first is none other than DHTML expressions.  DHTML expressions were a new feature in Internet Explorer 5 (back when the IE team was still attempting to innovate), however are still not used very often because of bugginess and performance issues.  I’ve also seen several IE bugs that cause the IE window to crash if an expression exists against an object that’s since been removed from the DOM.  I maintain that DHTML expressions (also called CSS expressions and “dynamic properties”) are quite helpful if used in very simple solutions, where the expression is something that can be resolved quickly as the IE DOM changes.

 

Expressions can be declared inline using a style attribute, within a CSS selector, or using script.  I prefer the latter two since it keeps things simple.  One of my favorite uses of expressions is to show and hide various UI depending on the state of a check box, radio button, or dropdown value.  It allows UI to be hidden if certain options are not selected, or allows for an easy implementation of a “Show Advanced” checkbox.

 

In my example, I’m creating a simple time sheet that shows hours worked per pay period, and allows the user to show various classifications of work (Actual hours worked, Planned hours, and Overtime hours.)  None of this uses script and it’s easy to see how it works, and doesn’t require logic complicated enough to warrant the use of a debugger (good luck debugging problems caused by expressions.)

 

Here’s my web page for you to copy into notepad and save locally:

 

<style>

   BODY {font-family: Arial; font-size: 11px;}

   TABLE {width: 75%; border: 1px solid grey;}

   TH {background: #BBBBBB;}

   .Total TD {text-align: right; border-top: 2px solid #999999;}

   .Planned {display: expression(cbPlanned.checked ? '' : 'none'); background: #BBBBFF; text-align: right;}

   .Actual {display: expression(cbActual.checked ? '' : 'none'); background: #BBFFBB; text-align: right;}

   .Overtime {display: expression(cbOvertime.checked ? '' : 'none'); background: #FFBBBB; text-align: right;}

</style>

 

<input type="checkbox" id="cbPlanned"><label for="cbPlanned" style="background: #BBBBFF;">Show Planned</label>

<input type="checkbox" id="cbActual"><label for="cbActual" style="background: #BBFFBB;">Show Actual</label>

<input type="checkbox" id="cbOvertime"><label for="cbOvertime" style="background: #FFBBBB;">Show Overtime</label>

 

<table cellpadding="0" cellspacing="0" rules="cols">

       <tr><th>Period</th><th>Date</th><th>Work</th></tr>

 

       <tr class="Total"><td>1</td><td>1/1 - 1/7</td><td>40h</td></tr>

       <tr class="Planned"><td colspan="2">&nbsp;</td><td>40h</td></tr>

       <tr class="Actual"><td>&nbsp;</td><td>&nbsp;</td><td>40h</td></tr>

       <tr class="Overtime"><td>&nbsp;</td><td>&nbsp;</td><td>0h</td></tr>

      

       <tr class="Total"><td>2</td><td>1/8 - 1/14</td><td>48h</td></tr>

       <tr class="Planned"><td colspan="2">&nbsp;</td><td>40h</td></tr>

       <tr class="Actual"><td>&nbsp;</td><td>&nbsp;</td><td>40h</td></tr>

       <tr class="Overtime"><td>&nbsp;</td><td>&nbsp;</td><td>8h</td></tr>

 

       <tr class="Total"><td>3</td><td>1/15 - 1/21</td><td>32h</td></tr>

       <tr class="Planned"><td colspan="2">&nbsp;</td><td>40h</td></tr>

       <tr class="Actual"><td>&nbsp;</td><td>&nbsp;</td><td>32h</td></tr>

       <tr class="Overtime"><td>&nbsp;</td><td>&nbsp;</td><td>0h</td></tr>

</table>

 

As you can see, most of the logic is within the <style> block.  Each planned work row has a class of “Planned”.  In the CSS definition for the Planned class, the “display” property has an expression of whether or not the cbPlanned checkbox is checked.  When the checkbox is un-checked, the display property of the CSS class becomes ‘none’.

 

Click Here to load this file in your web browser.

 

That’s it!

 

Mike – Web Dev Guy

Posted by mikechr | 5 Comments
Filed under:

Question of the day...

Here’s a hypothetical situation; you’re sucked into a worm hole and transported back to the year 1300 A.D. in Medieval Europe.  You didn’t bring back your cell phone, or laptop, or any “more recent” invention.  What advantages would you have over society at that time?  Would you be able to survive, and would you be able to influence the course of history?

More importantly, could you build anything [from scratch] that  hadn’t been invented at the time?

I was thinking about this and it occurred to me that there’s very little I’d be able to do.  I’m pretty sure, given enough time, I could generate electricity using magnetite or lodestone as magnets, and a coil of copper wire made from copper ore.  This would be something that hadn’t been seen before, but perhaps wouldn’t be useful unless I could harness it for something, perhaps light or heat.  Making a light bulb might be possible given enough time, though it took Thomas Edison quite a while to make one that lasted.  I’m not sure if I could do it.

How about a steam engine?  It’s a simple concept, but manufacturing the parts might take quite a bit of effort.  Provided you got the electrical current thing going, creating an electric motor might be the next logical step since it’s basically the opposite of an electric generator.  However, for this to be useful to anyone you’d want a way to store energy when you can’t generate it directly.  Creating a “wet cell” battery might be fairly easy.  What could you build to harness large amounts of current, such as a windmill or water turbine?

What else would be practical?

Any ideas?

Mike – Web Dev Guy/Modern Technology Specialist

Posted by mikechr | 7 Comments
Filed under:

Case-sensitivity with IE getAttribute

I ran across an interesting behavior in IE the other day.  Some of my script code was misbehaving, and it took me a while to track down the exact problem.  In one part of my code I had an onfocusout event that would update an expando property to a certain value.  However, when the object got focus again, I’d read the value and would find it was still set to the original value.  When I moved focus away, I’d update the value again and same thing.

After much debugging, I stepped into the code that set the original value.  It looked something like:

item.setAttribute("index", 0);

When I lost focus, I would update the value like so:

item.setAttribute("Index", 5);

Then, when I read the value back, I’d do:

value = item.getAttribute("Index");

However, the last line of code would return “0”, the original value I had set.  So, why wasn’t my value being updated?  Those of you intricately familiar with the IE DOM will already have seen the answer, it took me quite a while (mostly because of the thousands of lines of script code involved and the fact that in this modern era of technology, we still have yet to have a script debugger that really works well.)

So, let’s simplify the code down so you can run it in your own test web page:

<div id="foo"></div>

<script>
  function window::onload()
  {
    foo.setAttribute("index", 0);
    foo.setAttribute("Index", 5);
    window.alert(foo.getAttribute("Index"));
  }
</script>

 Upon first glance, you would expect to see a value of “5” on the screen.  However, upon running the code we see 0.  Why?

 Well, this has to do with the default behavior of setAttribute and getAttribute.  When setAttribute is called, the <div> will look something like:

 <div id=”foo” index=”0”>

 This is because setAttribute is case-sensitive and creates an expando property of the exact name specified.  The second setAttribute will do the same, and the <div> will look like:

 <div id=”foo” index=”0” Index=”5”>

 Since “index” and “Index” are different, two keys are created.  Now, when the value is read, IE looks for the first attribute matching the name “Index”.  Since getAttribute is not case-sensitive by default, it finds “index” with a lower case “i”.

 The best way to fix this behavior is to use the same casing for expando attributes, my original code was simply due to a typo on my part years ago that didn’t surface until now.  The other way around is to call getAttribute as such:

 window.alert(foo.getAttribute("Index", true));

 This will cause IE to be case-sensitive when searching for the value.  I’d disagree with the IE team (though it was probably some ECMA decision) on this point, I think names of expando properties should be case-sensitive like most syntax in Jscript.  Interesting lesson though, I learned to check with MSDN before assuming something was the case.

 Mike  - Web Dev Guy

Posted by mikechr | 1 Comments
Filed under:

More about type descriptors

The other day, one of my readers posed a question regarding my recent post “Data Binding to Custom Objects” – The question was essentially “Why are you writing all this code?  There’s much simpler ways to do the same thing.”  Well, the reader is correct.  There are many ways to do this same thing.   We’ll go over that in a second.  First, let me take a shot at defending myself.  All over the web, there’s thousands of web sites and articles, blogs and newsgroups, discussion lists and bulletin boards all about “how to do stuff in .NET.”  This is great, and it helps you find the information you’re looking for to solve the problem that you currently have in front of you in your day to day jobs.  However, the truly great programmers are the ones who know what’s going on behind the scenes.  Managed languages such as Java, VB and C# get a lot of criticism from the more “pure programmers” who prefer to work more low level with C and assembly.  Some claim there’s an entire generation of programmers who will never write their own memory manager, never create a linked list class from scratch, don’t know how a hash table works internally, don’t know how pointers really work, and don’t know the difference between memory allocated on the stack and memory allocated on the heap.  I would disagree and say that it’s not the language itself that’s directly responsible for this new “generation” of programmers, but the complexity of the APIs they depend on.  If you took the .NET framework out of C#, you’d have nothing more than a object-oriented language that still relies on the developer to construct these sorts of collection objects and design algorithms.  This is no different than the plethora of ready made objects MFC provides for C++ Windows programmers.  A language is simply an abstract way of expressing an idea, but those more familiar with the internal workings of a language will be the ones  who can exact their ideas in a clear and more precise manner.  Just because the .NET framework comes with a Hashtable class doesn’t mean you shouldn’t know how to write your own, and just because the .NET framework can take care of property descriptors for you doesn’t mean you shouldn’t learn how they work.

This new generation is not because of lazy programmers, or programmers who didn’t learn the basics.  Programmers in general will learn what they need to do their job, and no matter how low level you get, there’s always a level of abstraction.  Assembly programmers said this about C, C programmers said this about VB.  Until you want to write everything in pure machine code, running in ring 0, on your own CPU design that you soldered together in your basement, you’re relying on a framework that makes your job easier.  What’s to blame is this concept of “rapid application design” which VB started.  It became critical to toss together these quick little applications in a fraction of the time it would take with more low level languages.  IDEs started doing the boring work for you, which is great as long as you know what’s going on.  Which leads me back to my original point – there’s plenty of places on the net to find out how to do something, this blog is dedicated to explaining how things works underneath.  There’s only so far you will get memorizing what APIs to use where, but I promise you it’s always worth the time to really dig into something and learn what’s going on, for when you need to modify how something behaves or figure out how to fine tune something, you’ll have a pretty good idea of how to do that.

So use my article as a learning tool, this is how the data binding code works internally and this is how ADO.NET works inside.  Now, if you’re simply wanting to bind a collection of simple objects to a grid, you can rely on “default type descriptors” rather than generating your own custom type descriptor as described in my article.

Take the following class:

class Company

{

private string _name;

private string _address;

 

public string Name { get { return _name; } }

public string Address { get { return _address; } }

 

public Company(string name, string address)

{

_name = name;

_address = address;

}

}


It couldn’t be simpler, it has two string properties and a constructor.  I can bind it to the Data Grid like so:

protected void Page_Load(object sender, EventArgs e)

{

List<Company> list = new List<Company>();

list.Add(new Company("Microsoft", "123 Main"));

list.Add(new Company("IBM", "333 Main"));

 

Grid.DataSource = list;

Grid.DataBind();

}

 

My grid doesn’t change, it still binds to the “Name” and “Address” property of the object.  Internally, the grid still asks List<> for an enumerator, which List<> provides.  Each “Company” object in the list doesn’t provide a custom type descriptor, so a default type descriptor is used.   This type descriptor will look for a public method matching the names of the bound fields.  Note this must be a method, not a property (if I mark _name public and bind to that, I’d get a runtime error.)  This works great for the simple case, but those who used this method without first writing their own custom type descriptor would have no idea why this works, or how they can manipulate or extend this system to do exactly what they wanted.  Suppose later on, I wanted to provide some dynamic array of properties, such as items created by the user, or retrieved from a database.  I’d be totally lost and never know how to create my own custom type descriptors.  Hopefully some people out there got some use from my post, and there will be some better, more efficient code out there because of my efforts.

Thanks for the comments,

Mike Christensen – Web Dev Guy

Posted by