It seems like the spammers are getting deperate, I started to get Spam Bug Reports!
Will it never end?
It's one of those situations, where the very fabric of reality itself is wrapped. I'm feeling smart, because a prediction of mine (see the footnotes) came true, but my prediction was that I would feel like an idiot. I compromise by feeling stupid. I've wasted days trying to find out a problem in one of my ASP.Net pages. I just found it, and it was in a moment of enlightenment: "Oh, so that was it?"
I'm going to go over the scenario, so you can appreciate just how stupid the whole thing was:
· The page has user control that is being loaded dynamically. The choice of which user control to display is controlled via a drop down list.
· On the OnInit Event, I create the current control, and add it to the page.
· The page has also grid view that display a list of rules
· .When a row in the grid view is selected, a user control is created and added to the page (the previous control is removed), and the current control value is set to the new value.
· The problem occurred only when updating information (a row was selected, the UI displayed correctly, but when posting back, the values were never there.).
If you're an ASP.Net guru, you may have already realized where I did wrong. If you're not a guru, let me give you a brief overview of what was happening, one step at the time:
The user select a row, the page is post back with the new value.
The OnInit method is executed and the user control X is added to the page. It gets a default name of c00.
ViewState magic happens.
The select event handler for the gird view is run, and the first user control is removed, and user control Y is added. It gets a default name of c01.
The page is sent to the user, who update the page and save.
The OnInit method is executed and the user control Y is added to the page. It gets a default name c00.
The postback data for the control had the ID of c01, and there is no such control in the page now.
The view state contains data belonging to control with id c00, which exist on the page.
Ayende go raving mad trying to find why the control doesn't get the proper values.
No wonder that I couldn't reproduce the problem. It has to happen in exactly the right way for it to appear. The solution to it was to add one line to the base user control constructor, giving it a fixed name.
This post started out its life as a scathing rant after spending way too many hours chasing after a very silly bug (which I still didn't fix, and have no idea how to). I spoke with a friend about it, and he managed to put me in perspective, so this should be a more balanced post.
It's about ASP.Net and the model that it gives the developers who develop with it. Let's go re-iterate a few well known facts here:
- The Web is stateless.
- Humans are not.
Those simple facts are the basic reason that we've a complex architecture for ASP.Net. It attempts to bring state into the web. It mainly does so with ViewState and a few other tricks. One of the things that ASP.Net does very well is to give you a framework where you can build web sites very easily, by using self contained components that present a very nice interface to the developer, and a nice UI for the users.
The declerative approach allows ASP.Net to get rid of a lot of needless code (at the expense of increased compile times). I really like some of the stuff that I can do there. And 3rd party components can save you weeks or months of programming. For the most part, it works quite well. There are some problems with it, of course, view state bloat is a common one, but it is the less serious one.
The more serious problem is that you no longer work on the web. You are working on ASP.Net, and the web is abstracted away from you. And you know, if it was a 99% proof abstraction, I would love it. But it's not. It can't be. So I get into problems that I can't get out of because ASP.Net tries to do clever stuff behind my back.
A recent problem that I had was with a control getting the value of another contorl. The issue turned out to be an optimization for the ASP.Net engine, where viewstate seeks where done via indexes, and my controller was at the wrong index, at the wrong time. There is a (simple) solution for this problem, but finding out what the problem was took me over a day.
To be fair, most of the issues I'm running into seems to be on the edges of what should be happening (loading a dynamic control defined in a page from the master page, if the control has initial values, it ignores all other posts and maintain its initial values). This doesn't comport me very much, since I do not walk the straight and narrow. Not often, at least. Nor do I intend to. It's incredibly frustrating to see the problem, to know what is wrong, but to be unable to find out why.
A lot of the design choices made for ASP.Net make it much easier to develop for the web without needing to think about form variables, and query strings and cookies and all the rest of the fluff that interrupt our work when we want to add some business value (or just a cool feature) to an application.
I literally can't remember the time when I run into an HTTP level bug. In any platform, in any environment. The rules are very simple, and you need to do a lot by yourself. I like that. I can control everything from the HTTP stack upward. But this force me to handle variables myself, and to keep state between request, and to handle a lot of stuff that is simply time consuming and not really productive. At the end, I'll probably roll my own version of maintaining state between request. And I'm pretty sure that it, too, will be based on a hidden field.
But rolling my own means that I can go there and figure out what is wrong. I'm a member in the Castle Project, and that means that I am familiar with MonoRail on intimate level. MonoRail doesn't offer a state management out of the box, nor does it offer a rich toolbox full of ready-made components that you can use to create rich UIs by merely dropping item into the designer surface.
I'm going to completely ignore the design and maintainbility benefits of using MonoRail, and concentrate on a totally different aspects of it. First, it's keep me very close to the stateless model of the web. Which mean that I'm not deluding myself thinking that I can build winforms applications for the web. It means that nothing much is going on that I can't predict. There is a lot of magic in MonoRail, make no mistake. But it's a magic that is carefully trimmed to make sure it doesn't evolve into the Evil Witch of the West. The second part is that I have the source (and so can you). If something is going on that I don't understand, I can dig in and find it.
Problems like the ones that have been chasing me for the last few weeks would simply go away if I used MonoRail, since I would be able to control everything from the top down. But this control come with a cost. For instance, Infragistics has some nice looking controls, which I couldn't use if I used MonoRail*. If I wanted similar functionality, I would've to write it myself.
My thoughts on that? So what? I'm not going to implement each and every features of a pack such as Infragistics. MonoRail has some really nice ways to package common functionality. How long will it take to implement a basic grid, for instance (which MonoRail already has, btw). I mean, seriously, how hard it is to spit out an HTML table? Oh, you want in place editing? That isn't that hard either.
Yes, for the first application that I would write, I may need to write components that already exists for ASP.Net, but web components are usually simple. And when they are not simple, they are specialized. One of the reasons that ASP.Net components can be complex is that they try to be both simple and extensible and the same time, and sometimes it just breaks. They are either simple or extensible. Sometimes they are neither. For the second application (or after a couple of weeks have passed with the first one)? I already have those components. I can write the HTML to display just about anything you can imagine. And from there it's a simple matter to create a reusable MonoRail component.
To wrap things up, I think that it's pretty obvious where my stance is. The time that is saved using ASP.Net productivity features isn't higher than when using MonoRail. In fact, I would argue that it's the other way around. Certainly such problems as I've run into** recently caused me to lose time rather than gain it. You've to realize that I signed today and wished to be programming in VBScript using ASP 3.0, because at least then there was nothing much between me and what was happening. This is how frustrated I've became.
One thing that I liked in both MonoRail and ASP.Net is the level of support that I can get. In MonoRail I can talk to the people who wrote the code that is giving me trouble. In ASP.Net, I can (usually) do the same***.
Note: I purposefully left Ajax out of the picture, I'm not using Ajax in my current project, so I don't want to talk about things that I don't know.
*I'm pretty sure that this is a point in favor of MonoRail, but that is just in the case of Infragistics.
**Yes, I realize that at least in part it comes from not being completely knowledgable about ASP.Net 2.0.
***And Microsoft has been very helpful. I expect to get a response from them in the morning, probably a three line answer that explains what is wrong and how to fix it****.
**** I also expect to feel like an idiot in the morning. ("Oh, so that was what was causing it?)
I knew that I would appear somehwere in Eric's post about Super Programmers & Villians. I'm the zealot, take a look at my code, it has so many design patterns I can't really count them all. And just wait until you'll see what I'm doing with generics, anonymous methods and iterators in C# 2.0.
*Evil Laugher fading into the distance...
It finally caught on to my site. I'm now investigating the options and the reports it generate.
It has some interesting information to show. I'm going to add it to the blog as well (right now it's only for the main site). There seem to be a lot more interest in NQA than I thought there would be.
I've a page that loads a control dynamically, based on a drop down list that the user selects. I want to add the control to the page, and have it work like any other control on the page. A dynamic control in ASP.Net doesn't persist between page post backs unless you add it each time the page load. Now, here is an interesting problem. You can add controls to the page just about whenever you want, but if you want their view state and the form values to be loaded properly, it must be done in OnInit().
So far so good, I thought. I had just one problem. I needed to add the control based on the value of another control, and I would get that until the view state / form values was loaded. But if I waited that long, my dynamic control wouldn't be bound to the form values that it should have.
My solution was to manually extract the form value of the drop down list and create the control in the OnInit(), the issue here about submitting the page. For some reason I'm losing the values of the controls in the dynamic control. I always gets the old values. I can't find out what is going on there, and I can't get a simple reproduction to show the same problem. The worst part is that it is working consistently when I've saving things, but not when I'm updating them.
I tried to re-create the same situation in a sample project, but there it is working properly.
I burned two days on this thing already, and I'm not sure how to solve the issue. I know that it's probably just something that I'm missing with save / load, but I'm not sure what is going on there. I read enough material about the ASP.Net life cycle to suffice me for a lifetime, but I can't figure out the answer. I think that this may have to do with the fact that the button that generate the postback is outside the user control.
The values outside the user control update normally, which make it all the more frustrating.
Here are a couple of interesting statistics about Rhino Mocks that I pulled from Cuyahoga. For this table, I merged the results of Rhino Mocks for .Net 2.0 and for .Net 1.1. You can see that the distribution of releases is pretty standard, a flurry of releases, pause, a flurry of release, etc. Rhino Mocks 2.4 is the most popular download, it was the version that added .Net 2.0 features.
Rhino Mocks 1.0 was based on EasyMock.Net, I abandoned the code base after it proved to be too hard to maintain and since it used remoting proxies under the cover, which weren't always compatible with the types being mocked.
|Title||# of downloads||Date published|
|Rhino Mocks 2.5.2||0||22/11/2005|
|Rhino Mocks 2.5.1||28||20/11/2005|
|Rhino Mocks 2.5.0||9||19/11/2005|
|Rhino Mocks 2.4.2||144||22/10/2005|
|Rhino Mocks 2.4.1||71||12/10/2005|
|Rhino Mocks 2.4||272||26/8/2005|
|Rhino Mocks 2.3.5||42||25/8/2005|
|Rhino Mocks 2.3.4||87||19/8/2005|
|Rhino Mocks 2.3.3||150||18/8/2005|
|Rhino Mocks 2.3.1||76||17/8/2005|
|Rhino Mocks 2.3||102||16/8/2005|
|Rhino Mocks 2.2||127||12/8/2005|
|Rhino Mocks 2.1||67||11/8/2005|
|Rhino Mocks 2.0.7||113||31/7/2005|
|Rhino Mocks 2.0.6||57||30/7/2005|
|Rhino Mocks 2.0.5||63||29/7/2005|
|Rhino Mocks 2.0.4||85||19/7/2005|
|Rhino Mocks 2.0.3||57||18/7/2005|
|Rhino Mocks 2.0.2||109||15/7/2005|
|Rhino Mocks 2.0.1||75||13/7/2005|
|Rhino Mocks 2.0||113||2/7/2005|
If you ever viewed the output of the HTML from Word/Excel, you've noticed that it's ugly, and often only works on IE. Here is a simple trick to clean it up using regexes (you can use it in front page, visual studio, notepad2, etc).
For Excel, replace "<td [^>]+>" "<td>", and for Word replace "<p [^>]+>" "<p>".
It's the easiest way I know to clean up large documents.
I'm going to interrupt the regular streams of rants and useless information in order to focus on something beautiful. It this morning, I went outside and then and the view took my breath away. I run back inside and got a camera, and snapped a few photos:
In front of my house, I snapped this photo while it was raining.
A short while afterward, I took this photo while watching from a balcony in a mall nearby.
Some time ago Eric Sink posted about people who complained about the bugs in VS 2005.
The six billion people of the world can be divided into two groups:
- People who know why every good software company ships products with known bugs.
- People who don't.
It goes on in the same vein for another four thousands words, giving some good examples form Eric's own product, SourceGear Vault. I agree with Eric in pricipal. Hell, my software has bugs that I said I Wont Fix. Although I do try never to release with known bugs, I've done so in the past, and will probably do it again.
I was very surprised by the reaction that a couple of blog posts had. Hell, there was even a comment about it in DotNetRocks, citing "obscure problems". What I think Eric and a many others are missing is the cause for all the noise. It wasn't the bugs themselves. The list of people who complained include people who worked with software for many years. They*certainly had to make the same decisions in the past.
The issue here was support. And that issue was painful. It's okay to have bugs in your software. I may not agree with Microsoft on the items they decided to go to RTM with, but I understand that they have to triage those bugs with an eye to other factors than what-will-make-Ayende-happy**. What really bothered me and many othes is that there was the very real possibility of living with those bugs for ~2 years or more.
I still struggle with the slow refactoring in web projects. I'm using a pre-beta product because it's better than VS 2005 has. I just run into a very nasty edge case, where a random control gets the values of another control. I can assure you that the level of frustration that I had dealing with this bug is unprecedented on .Net 2.0. I currently have another problem where code that should work doesn't, and I'm not really sure what the hell is going on there that muck this up. Can you imagine this going on for two years or more?
As soon as Microsoft made the anouncement about releasing a service pack for VS 2k5, all the blogger just let the subject drop. It's not interesting anymore. Sure there are bugs, but it's a fact of life, and they will be fixed. The above mentioned problems? The edge case I run into is a change in the way ASP.Net 2.0 handle the view state, it's actually documented and there is a way to fix it. The current bug will probably turn out to be something similar.
The main difference is that I no longer feel as if someone threw a lot of code at me and told me that they will be back in a couple of years to see if something is wrong. That made all the difference. Nothing much has changed, but knowing that we aren't abandoned until Orcas ship is a huge difference. As soon as the anouncement was made, all the complaints had died down. The bugs will be dealts with, not all, and not by next week, but they will be.
That said, I'm still holding Microsoft to a higher standard than I'm holding the rest of the industry. They consistently manage to put good products out, and they do it under very different constraints than most developers need to meet. When you're so big, you've got to take more care.
* I'm not sure if I should include myself in the list. I don't have much of a professional experiance.
** If anyone wants to use this metric, I'll be happy to deliver the Methodology of Making Ayende Happy.
Eric Wise it talking about super coders, and promise to talk about super villians.
I liked the super coders, but I can't wait for the villians.
I recently had a problem in ASP.Net that was certain to put me in an asylum. Here is the story:
I've a page that loads controls dynamically. On postback, the page would replace the dynamic control with a different one. Both controls had a drop down list, each with its own ID, each with its own values.
The problem that I had was that for some unknown reason, the values from the first list were copied to the second list. I had no idea what was happening, and I was one step away from finding just how strong the walls are*.
Eventually a friend found out the answer. Apparently ASP.Net 2.0 uses indexes instead of IDs to figure out which view state belongs to which control. By some freak accident, I managed to stumble on the one occasion where this would be a problem. The solution to the problem? Just decorate the controls you're loading with ViewStateModeById, and you're done.
One thing that I noticed is that it's not possible to mix & match controls with this attribute and controls without it. I get view state exception when I try to do that. It doesn't bother me one bit, since the exception at least remind me that I need the attribute, and that would save a bug to fix later.
* For instance, are they stronger then my head?
Okay, I'm not sure how to express it, but one of the major things that made previous builds of ReSharper hard to use was the IDE coloring. The issue is an VS 2005 bug that made the code look like crap.
Actually, the 210 default coloring (teal background for parameters and yellow variable for local variables is not bad*), but after a while it decide to paint the method names as white on black, which is Not Nice. Build 210 comes with an option to turn that off, which means that now I have a much better experience using it.
Something bad, to balance the good, ReSharper doesn't know about controls you define in ascx files (but it does know about aspx files).
*It make finding out those "name = name;" bugs in constructors much easier.
I'll be the first to admit that I don't know much about ASP.Net UI. (I know a bit about how it works, but UI is a mystery for me).
I needed to display a page that would allow you to add rules to an object. There are different kinds of objects, and each one has a different set of rules. I knew from the start that I would probably need common functionality for all objects, but I couldn't really write something yet, because I didn't really know what I was going to do.
So, I wrote the first page as if I had no more pages to write, and then I wrote the second page. I did that by mainly copying & pasting and just changing a couple of values. It was really quick to do, and I moved to the third page using the same methods.
Now I knew what the common parts were, it was supposed to be a simple matter to refactor it to remove duplication. It took me a while to do it, and I'm pretty sure that it's not the "proper" way to do it.
I've a master page for those pages, to which I added ChildPage property that accepts a certain interface with the operations that were different from page to page. The pages that use this master page register themselves on the PreInit() method, and then it all comes together. There is some non trivial logic in the master page, since it needs to manage dynamic controls that change on the fly.
As I said, I'm not an expert, what do you think of this solution?
· It finally has some formatting options for anonymous methods, which is a blessing for me, since I use them just about everywhere.
· You don't need to search for their ReSharperKbd.vssettings file, there is a nice button that will do that for you, just like in Resharper 1.0. It doesn't seem to work in this build. Importing the file from %AppData%\JetBrains\ReShraper\ solved the problem.
· There is still a problem with the coloring, but at least now it has sane coloring for method parameters and local variables. The coloring of breakpoints is still not nice. This means that I can't really see at first glance that it's a breakpoint. It's a problem with VS 2k5 that should be solved in a hotfix soon.
· Memory usage seem to be very high (~120Mb), for an 8 project solution with ~20 KLOC in all (but with a lot of assemblies that the solution use).
· I like the way it orders the namespaces alphabetically.
· It doesn't have intelli-sense in aspx files, and I turned off VS's intelli-sense, since ReSharper's is so much better.
· It supports intelli sense of members declared on aspx pages, which is nice.
· There seems to have been a lot of work on generic support, which was very weak in previous builds.
· When a file is opened, you can see the VS2k5 default colors for a second, and then it repaints with ReSharper colors.
· It feels so good to have a tool that is smart enough to figure out what I want to do, and actively help me to do it.
· There is a load of small things that are wonderful, for instance, try to go to a child object, and if it's an asp.net object, it will ask you if you want the aspx or the aspx.cs file. It's surprising to see such polish in an EAP product. But then, I put JetBrains on a totally different level when it comes to making sure that I will enjoy working with their products.
· It seems to have a problem recognizing inherited items from a generic class (where the sub class is not generic).
Please remember that this is alpha software, so it's really cool to see how they improve the product from one build to the other.
I'm not sure if I will carry on using this build. On the one hand, it's highly needed, but on the other, it's still not ready for it. I'm afraid that I'm probably going to run into all the rough spots in the product, since I tend to take advantage of just about every feature I can lay my hands on.
I can just imagine how cool the final version is going to be.
JetBrains, keep up the good work!
This looks cool. I could certainly have used that a while ago.
I wonder how you turn if on/off in production.
There is a saying in the IDF:
If it doesn't work with brain, use force.
If it doesn't work with force, use brute force.
If it doesn't work with brute force, use the 5kg hammer.
And if it doesn't work with 5kg hammer, call the heavy artillery,
and run away very fast.
I read a lot, and I found this post by Jeff very interesting. He talks about a research made about difference in reading speed with fonts, and that the Courier, the default programming font in Windows, was the second worst font of them all.
Why is it that developers usually like to develop using mono-spaced fonts, then?
I think that it has to do with how we read. I find that I usually don't read the letters, I read a word. And I often don't bother with looking at the spelling or the way it's pronounced (one of the reasons that I sometimes speak strange English). I look at the shape of the word, and go on to the next one. It's worse with names, since I usualy just grab the first recognizable sequence and then carry on. I read a great book once, and was raving about it to a friend of mine. But when ask how the hero was called, I said something like: "Um, it starts with a Bu-something".
In code, I often look for sequences that repeat, and I try very hard to make sure that I never need to read large amount of code at one time. (Large being anything above ~30 lines of well spaced and clear code). Monospace font make sure that I can be even more lazy, since everything always looks the same, and I can line things up so they would look nice when I scan them again.
How do you read?
I almost always work with dual monitors, I just can't bear to be limited to one screen, especially as I always work with maximized programs, so it's good to be able to see two at the same time.
When I'm using Visual Studio, that is all I'm using, so it's good to have as much screen real estate as possible dedicated to it.
I'm going to try that tomorrow, and see how it goes.
I guess the geine has decided that it should extend its reach, now I've got a bug in Google. More spesifically, google analystics.
There is a new build out, build-210, of the greatest boost to productivity since the syntax coloring :-D
Go get it here. It is mildly frustrating, to put it mildly, to get almost all the features that I so crave, only to put them away again because it's still alpha. What is cool is that you could actually see it improving every week or so.
I don't usualy talk about politics, but this time I would like to make an observation to anyone who is interested in Israel politics. After the election of Amir Perech as the leader for the Avoda (Labor) party, there seemed to have been a huge shift in the political landscape in Israel.
For the first time, there is the possibility of an election where the main focus is not about peace or security, but rather the social issues. I currently don't hold an opinion about any of the parties, but I definately like the way it is going. An election focused on social issues is due for a long time. Peace is important, and saving life is more so, but I don't see that much of a difference between any of the candidates regarding the peace process or protecting Israel from terror.
Regardless of who will will the elections, it put a whole new spin on the political arena, one that the politician had conveniently ignored for "more important issues" for too long.
Am I a bad person? I don't think so.
So why do I keep running into every edge case in every software product that I use? Take a look at this problem, it took me quite some time to figure out what the problem is, since I just couldn't believe what was happening. And I still don't know the why. I think that I'm going to have to start Reflecting over the ASP.Net assemblies, just to figure out what is going on there.
Why me? I'm just interested is showing a silly form, and I run into those things. I know that there are people who build systems with multi million lines of code that never run into the bugs that I run just by opening the IDE and typing "Hello World"*. I'm not sure if it's that I'm not using the tools/product properly, or that I've an evil genie really hates me.
That bug had me raving and cursing in no time at all, and as usual, it appeared out of nowhere, just when I was trying to finish writing a page and extract duplication. Now I got both the duplication and the bug to deal with, argh.
* True story: It took me 5 hours to get my first C# program to work.