and has 0 comments
A while ago I wrote a post about the bug in the DataTable.Select method with columns with comma in their names.

Today I discovered another bug, when using DataTable.Select with an empty sort string, but not an empty filter string, there is an implicit sorting by the first column. Short example: a DataTable with a single column called "words" containing values c,b,a,d , when Selected with a filter like "words is not null" and a null or empty sort string, will return a,b,c,d.

The only solution for this was to drop DataTable.Select entirely and use DataView, with its NET 2.0 method DataView.ToTable. So the code to take a DataTable and return the filtered and sorted table would look like this:
public static DataTable Select(DataTable table, string filter, string sort)
{
if (table == null) return null;
var dv=new DataView(table);
dv.RowStateFilter=DataViewRowState.CurrentRows;
dv.RowFilter = filter;
dv.Sort = sort;
return dv.ToTable();
}

But DataView has the same problem with columns with comma in their names. We solve it in the same way we solved it in the previous post: we change the column names, the sort and filter strings, we select, then we change the column names back:
public static DataTable SelectSafe(this DataTable table, string filter, string sort)
{
var originalColumnNames = new Dictionary<string, string>();

foreach (DataColumn dc in table.Columns)
{
if (dc.ColumnName.IndexOf(',') > -1)
{
var columnName = dc.ColumnName;
var safeColumnName = columnName.Replace(",", ";");
var reg = new Regex(Regex.Escape("[" + columnName + "]"), RegexOptions.IgnoreCase);
dc.ColumnName = safeColumnName;
if (!String.IsNullOrEmpty(filter)) {
filter = reg.Replace(filter, "[" + safeColumnName + "]");
}
if (!String.IsNullOrEmpty(sort)) {
sort = reg.Replace(sort, "[" + safeColumnName + "]");
}
originalColumnNames[safeColumnName] = columnName;
}
}

var newTable = Select(table, filter, sort);

foreach (KeyValuePair<string, string> pair in originalColumnNames)
{
table.Columns[pair.Key].ColumnName = pair.Value;
newTable.Columns[pair.Key].ColumnName = pair.Value;
}
return newTable;
}

and has 0 comments
At first I thought it wasn't Linkin Park singing. The sound is a bit different, at least in this song. But I like it. I hope this new album of theirs, Minutes to Midnight, will be as good as their first.


There is an article here that explains it better than I would. Basically, the new Visual Studio is finally released in beta and is supposed to be the IDE for .NET and Vista.
The .NET Framework 3.5 (that is 2.85 in normal versioning? :D ) is also to be released here.

and has 0 comments

I know, the third entry in my blog about Basescu doesn't say much about my IQ or style, yet now I know what I felt I needed to say, but didn't realise what it was. It is the similarity between the case of Traian Basescu and Ariel Constantinof.

It is amazing still that these two similar stories happened in the same time. Indeed, Basescu is like a high school student who is suspended from the school on the basis of his behaviour, without anyone really knowing if it is "kosher" to do so. Do the high school owners have the right to expel Basescu or is this a financially motivated blunder? Both of them are big mouthed smart asses, without being really malevolent, yet being rather naive. Just as Basescu, Ariel gets a lot of sympathy from bloggers and radio hosts (radio bloggers?) everywhere, but without any true support. On each of the blog pages that describe his ordeal there are hundreds of people that offer their moral support, but really not much else. Just as Ariel, Basescu gets only a bunch of people to at least voice their anger to the school directors.

Can the case of Ariel Constantinoff serve as a simulation of what will happen to the country in a few months? I don't know, but I really like Ariel more than Basescu. And at least he has parents, the chance to go to another school. For crying out loud, he's a kid! Teachers, leave the kids alone! But who will find enough sympathy in their hearts for an old, bald, shunned ex president who didn't yet catch on with reality?

That's it! No more Basescu for a while on this blog ;)

I just remembered this song and, since I haven't been posting music lately on the blog, I put it on. The clip is made by fans of both Lou Reed's song and of the movie Trainspotting, also a favourite of mine, which featured A Perfect Day in the soundtrack. Enjoy!

A previous post of mine detailed the list of ASP.Net controls that cannot be used with UpdatePanel and ASP.Net Ajax. Since I provided a fix for the validators earlier on, I've decided to try to fix the Menu, as well. And I did! At least for my problem which involved using a two level dynamic menu inside an UpdatePanel.
Here is the code:
<script>
function FixMenu() {
if (typeof(IsMenuFixed)!='undefined') return;
if (!window.Menu_HideItems) return;
window.OldMenu_HideItems=window.Menu_HideItems;
window.Menu_HideItems=function(items) {
try {
OldMenu_HideItems(items);
} catch(ex)
{
if (items && items.id) {
PopOut_Hide(items.id);
}
}
}
IsMenuFixed=true;
}
</script>

Now all you have to do is load it at every page load:
ScriptManager.RegisterStartupScript(this,GetType(),"FixMenu","FixMenu();",true);


Explanation: the error I got was something like "0.cells is null or not an object", so I looked a little in the javascript code, where there was something like " for(i = 0; i < rows[0].cells.length; i++) {" and rows[0] was null. All this in a function called Menu_HideItems.

Solution 1: Copy the entire function (pretty big) and add an extra check for rows[0]==null.

Solution 2: Hijack the function, put it in a Try/Catch block and put the bit of the original function that appeared after the error in the catch. That I did.

...which is the Romanian word for "The people". Something a little archaic, like in the old days, when the people were either being oppressed, discontent or revolting. Usually, one uses the word in describing folks living in the country or a people as a whole, but then they are always specifying the country.

These days, right after the Parliament decided to suspend president Basescu, the Romanian Internet went wild. "Poporul" that, "Poporul" this. Blogs everywhere, hailing the great hero of "the people", victim to the vicious plots of traitors and communists and economic interests and so on and so on.

I am not even commenting on the decision to suspend Basescu, although I never liked the guy, but I can and will comment on the reaction of so many people, fellow bloggers, journalists and opinion leaders, all caught in the demagogic and cynical trap of the "hero".

For example, I read that Basescu (single-handedly, no doubt) brought Romania in the EU. Wrong! Most of the job was done by the PSD before, and it would have been inevitable, anyway, since the EU wanted our market. He is also responsible for the transition from the ROL (the leu, the old Romanian coin) to the RON. I might argue that the transition itself is dumb and useless since we will be switching to the Euro in 5 years, but hey... what did the president of the country in order to influence in any way the switch to the RON? Again, he is a great guy, but he did this terrible mistake of putting Tariceanu as prime minister. Did he have any other choice?! He won the elections (barely, I might add) on the back of a coalition of parties, the democrats and the liberals. Being a democrat himself, he had to put a liberal prime minister, whether he wanted or not! What else did he do, this hero of the people, except telling Bill Gates that piracy was a positive thing for Romanians? (which is true, BTW) Publicly fighting with your prime minister is NOT a good thing.

The greatest thing Basescu ever did was impersonate fantastically well a man who fights corruption. But did he? Corruption scandals are everywhere around him, involving him, suggesting political blackmail by use of the Secret Services. Are they based on anything? I don't know, but I do know that the little corruption, the one that I have to face, as a normal person, did not diminish. Quite the opposite! The current government policy seems to be take from the small and give to the big.

But returning to the people, who are these people that like Basescu? The ones that are either sympathizers of the democratic party or not having any political sympathy (as all other parties are now against him). Who are these wonderful people who will fight for the symbol of their freedom and fight against evil (no, not Bush), against the political will of all the parties and the people that support them and against all the TV attacks against the president? Who are these great minds who can think for themselves and make a decision and stick by it? They are not the "popor", that's for sure!

So for you, all these people of the press and Internet blogging bravado, I suggest you speak of yourselves, leaving "the people" alone, since you are not their representatives (as Basescu is not). Leave the illusion of greatness to the dictator-hearted people. Lead by example, not by association. Because you are not of the people, you are a little better.

and has 1 comment
Well, it sounds better in Romanian, since just a few days ago it was Easter.

Anyway, it seems that the dark force that rules Romania has finally shown its ugly head and took vengeance on president Basescu. You see, some say the country is ruled by corrupt politicians, while others blame economic interest groups. But it's all a scam to hide the real rulers of Romania: the boutique traders!

It all started quite a long while ago, when Basescu was only the mayor of Bucharest. Back then he decided to demolish boutiques that provided cheap and accessible nourishment and drinks to the population and to kill as many dogs as possible. Their plan was long and elaborate, but the boutique people got through all of this without even being noticed. They and their dogs, saved from certain death by their covert operations. Finally, the day has come! Basescu was allowed to go as high as he did only to have a bigger fall in the end.

You might consider this post another tasteless joke from my part, but you will see... some day... when Basescu has lost all his political support, nobody loves him, his beautiful Presidential residence taken from him, feeling defeated, buried in despair... the dogs will get him. Oh, yeah, they will get him. They never forget!

Did you get a "0.cells is null or not an object" Javascript error while trying to use UpdatePanel and something like Menu or TreeView? The reason is that some controls are incompatible with UpdatePanel! Most amazingly, the newest controls seem to be the least compatible.

You just copied a directory with an ASP.Net web site in your wwwroot directory, you created an ASP.Net application from IIS/Web Sites, yet you get an error, no matter what page you try to access: The web application you are attempting to access on this web server is currently unavailable.
It's an access issue. Give access to the directory to the ASPNET user.

and has 9 comments
I've wanted to write about this for a long time now. It started with the entry about the ridiculous and diabolical street sweeper machines that make lakes of water at every intersection while "cleaning the streets and fixing the dust". As an added bonus, now entire forests outside Bucharest are being torn down to make way for housing projects. I wonder where the dust is coming from, hmm...
Anyway, I want this entry to be as complete as possible in order to tell anyone considering buying a bicycle to ride in Bucharest what exactly they are getting into.

Step I. Buying the bicycle



Now, being a girl or a slim guy and not having the desire to make bike stunts in the foreseeable future, you might be considering buying a bicycle from a hypermarket chain like Cora. Don't do it!! The bikes there are of bad quality to begin with, but considering the people at a hypermarket don't know anything about bicycles, you will also get a bike that is put together by marketeers.

Let me give you an example: the bike is twice as cheap as anything you saw in a bike shop, it also has a lot of accessories like wheel covers, water bottle support, ringer, bike support leg. Isn't that a good deal? No! The spikes of the wheels are bad Chinese quality, in short time your wheels will turn in an figure 8 like movement; the water support is nothing but a glorified wire, sooner or later you will deform it and it will scratch you or your clothes; The ringer works, but is placed in the middle of the bike horns, so you can't reach it; the wheel covers are cheap plastic and they will always fall on the wheel making loud noises and slowing your bike; the bike support leg will at first not hold your bike, since it is really bad, then it will get its mechanism jammed and you won't be able to expand it.

Still want to buy it from Cora? So where do you buy a bike from? I personally despise franchises. That's why I would not recommend First Bike or any other shop like it. However, not having bought anything from them, I can't express an opinion. I bought both my bikes from Magelan and I am rather satisfied with the bikes and the service, even if I had to pay a little extra. What is nice about Magelan is that they are a full time bike shop. They fix bikes all day long as well as sell them. They taught me about how to maintain my bike, they centered the bike wheels (this being a very important process if you don't want your wheels to deform or the bike to require more effort to ride), etc. They also presented me with bikes of 1000-4000 euros :) Luckily, you won't have to buy anything more expensive than 400 euros.

The things you want in a bike are: wheel covers (see the diabolical street sweepers above), firm brakes, an anti-theft device and a good saddle. Anything else is rather useless. You will need a bicycle pump, but I would recommend the foot pumps that are sold in car shops, not the arm muscle devices the people at Magelan sell as pumps.

Step II. Transporting the bicycle



What do you mean, transport the bike? It should transport you, right? Wrong!. The bicycle will transport you only on the road. Then you have to move it upstairs to your flat or to your office. Sometimes, like when you go shopping, you need to lock your bike and tie it to something. You will soon notice that moving your bike with an elevator is not an easy task, especially if you are tall like me and you bought a big bike. There are also old hags that insist on you cleaning the elevator after you dirty it with your bike wheels. There are blocks without elevators. The first rule about this: don't tie your bike downstairs, hoping it won't get stolen. It will!
If you have the misfortune to live in a block without elevators or with a too small one, you will have to climb the stairs with it. For example I have to do this at the office, but lucky me, it's only at the fourth floor.

Step III. Riding the bike



Oh, this part is going to be long. Take some popcorn and read carefully.
At first you will ride the bike on the sidewalk. It makes sense, since you want to be safe when you make rookie mistakes and you lose your balance. You don't want a big truck to hit you when you stop suddenly and can't keep straight. So, if you are allowed to move on the sidewalk and it's safe, you could always use the sidewalk, right? Wrong!

In a normal situation, where the city hall really thought about you, the citizen, and took measures to keep you happy, you would be OK using the sidewalk. There would be no holes, there would be easy access from the sidewalk to the street, no cars parked on the sidewalk, no cars running on the sidewalk. In Bucharest no one even considers bikes. There are holes in the sidewalk, since you have feet to go around, in or out of holes; sometimes there is a lower sidewalk edge for things like bikes, wheelchairs and child perambulators, but sometimes it is a bit too high for comfort or there is none; when there is, cars are parked in front of them and, at the street crossings, people stop on them, without even moving out of the way when they see you sitting on a bike next to them. That is, if you can move on the sidewalk at all, since cars try to beat the traffic by moving on the sidewalk or they just park there, blocking the way. Not to mention the weird thingies that one meets on the sidewalk: people!

There are three "banes of the biker" when moving on the sidewalk: lover pairs, old people and women with children. So, if you see an elderly couple that seem still in love walking with their nephew, at least go around them on the guy's side. Why are they banes? Lovers like to hold hands, while in the same time keep apart from each other, then suddenly get back together and split again. They are completely clueless, unaware of the world around them and totally unpredictable. Old people are equally unpredictable due to strange and unspeakable pains, aches and mental conditions. They can stop suddenly, zig-zag, turn around unexpectedly and, most of all, get completely freaked out when you pass by them (even at a few meters away). Women with children are firstly women, then they have children. I rest my case.

So, after a while you get annoyed with all this, you decide to move it to the next level: the street. Since the circulation rules regarding bikes are pretty clear, there shouldn't be a problem. Cars will leave the "ecartament" empty, not park there, they will move one meter away from you when they pass by you, the drivers will be civil and respect your legal status of vehicle. Rrrright!

Street "biker banes": women driving new cars, taxi cab drivers and men driving junk cars. Women with new cars usually cheated through their driving licence exam and the car is not even theirs. Someone probably bought it for them. Women in general have a strong sense of law and order, therefore they will expect you to obey every circulation rule they know of and, when faced with real life situations that are not in the bloody book, they panic, freeze, etc. Simplest way to solve this is to always consider the possibility they actually want to hit you and take precautions against it. Taxi cab drivers own the streets. They are afraid of nothing and no one, except other taxi cab drivers. And women in new cars. And men in junk cars. For example, a cab driver will always move on the tramway line and honk at you, explaining in vernacular why he has the right to be there and you don't. But it is understandable... they rarely take Latin. Anyway, the men in junk cars are careless. They know they can buy a car the next day just like the one they are driving. It will be junk, but whatever you hit or hits you, they have to pay more. What could happen in the worst case scenario? Die? They already lost everything. And worse of all, they have a junk car, which is humiliating. They try to cover this shame with loud music, usually bad music, which makes them not only dumb, but also deaf.

When you learn to avoid the banes you still have to fight the street sweepers, to learn to move quickly when the light goes green, as drivers will magically ignore you being there when they turn right and you want to go forward. And most of all, you will have to fight the "good" ideas of the city hall.

Example: they built this bike track (weee!) around the Alexandru Cuza park (formerly known as the I.O.R. park). It is a half a meter wide strip, marked with yellow, right in the middle of the sidewalk, with beautiful images of bikes drawn on it and occasionally some arrows to point out the direction. So, anyone wanting to circle the park in one direction, like a hamster in a wheel, can use this. Of course, last time I saw it, there was a cripple guy walking with dignity on it. At least he respected the direction pointed by the little arrows.

The city hall also plans to build bike lanes. A commendable effort if they didn't do in the same time things that nullify it completely. And I mean the street side garbage bins. These are the bins that drivers can throw stuff in. Of course, they are right on the side of the street, the place where the horns of your bike are supposed to be when you pass through there. Not to mention the remote possibility that any Romanian driver would want to throw things in the bins rather that directly on the street, in which case they would most likely not look behind before putting their hand out. Can you spell "open fracture"?

OK, OK, I don't want to scare you out of it. It's just that there are a lot of morons out there. You need to pay more attention, else you will get hurt. Once you understand that the world is a dark evil place that wants to cause you pain, you will be alright!

Step IV. Taking care of your bike



Your bike needs to have the wheels firmly inflated. A car has the wheel pressure at about 2.4 atmospheres. Your bike will require 3.0-3.2. That means regular pumping or, the lazy man's alternative, fill them up with air at any gas or vulcanization station. Also, if you have a flat tire, all you have to do is pay a guy at the nearest vulcanization 1-2 euros and he will take the wheel out, check the tire, fix it, put it back on. Some would be kind enough to refuse, just go to the next.

After you used it for a while, you need to take it to be checked. Not too often, like once or twice a year (recommended default value). Go to Magelan, no matter where you bought the bike from, and ask them to check it for you. They will do everything there is to be done. The service is really cheap, too.

That was a short chapter.

Step V. Miscellaneous



So you know where to buy it from, what you want on it, how to ride it, what to look out for and how to take care of your bike. What else is there?

Well, first of all, sweat. When on the bike one doesn't usually sweat as the air circulation quickly evaporates the humidity and cools the body. However, stopping is a bitch. All the heat builds up quickly in your system, now used to have external ventilation, and you start to sweat. So, when you get to the office, don't rest, don't catch your breath, take your bike up as soon as possible, go to the bathroom, remove your t-shirt, wash. Use a special towel that you brought with you or that you designated as body towel. You will have a lot of perspiration on your spine and on your chest. Your face will probably be very sweaty, too. Take your time. Your body needs to cool off, so you might need to splash water on you repeatedly.
If you do this, you will need no change clothes and you will be fresh and reasonably not stinky for your colleagues. You will rinse your mouth with water, but don't drink any until you get out of the bathroom and you are reasonably cooled down.

Also, special attention to buses. It is easy to go by them, as they stop often. But they also release those human thingies, sometimes before the bus station, sometimes they start from the station and they stop because they see some guy running after the bus or someone forgot something and they want to get off. Sometimes bus drivers do it on purpose.

The same thing goes for every car stationed at the stop light. The only accident I had with my bike was when a complete idiot opened the car door at the stop without checking if anything is coming. I slammed right into that door. The scary thing is that I also got out of a car at the red light and I realised I didn't even consider checking for a bike. So it happens to everyone. Go slowly by the cars at the stop!

The last thing: etiquette. If you are a girl, not necessarily a stunning image of womanly perfection, you will get honked, whistled at, disrespected, teased. The only ones that will not do that are the women, which, as stated previously, will silently come from behind and kill you in inept panic. Don't get mad, don't get even, just learn to let it go, ignore everything that doesn't have anything to do with you getting to your destination. If you are a guy, you will be challenged at every step of the way. Or is that at every wheel turn? Anyway, drivers will try to bully you, block your way, honk you out of composure. Same advice goes to guys as well: ignore anything that is not about to be in your way or hit you.

What you need to understand is that, in normal Bucharest morning traffic, you are faster than any car there. People that spent their entire economies and still paying huge rates at the bank to have their new car will see you pass right by them, not paying for the car, for the gas or caring about the traffic! There is a lot of frustration there, don't give it a chance to bubble up towards you.

No matter the genre, you will have to either wait for someone to pass on a street crossing and provide you with "cover" or you will have to descend from your bike and walk next to it on the crossing. This is the only rule that one would reason out of, since it it more advantageous for drivers to let you pass on your bike (since you will cross faster) than on foot. Yet 99% of them will ignore you wanting to cross the street while on your bike. It's a pride thing. Bow to the king.

If you got this far, then you probably should get a bike, it means you are committed :) It's not as bad as I portrayed it, either, but pretty close. Danger comes not from what you expect, but from the unexpected. You also expect less when you are not paying attention or are thinking of something else. I don't recommend music listening when you ride the bike, but I do recommend sun glasses and (didn't try it, yet, but soon) a face mask/air filter.

and has 0 comments

Update 2nd of July 2008:
The solution below doesn't always work. For a validator to not work you need to have .NET 2.0 installed without installing Service Pack 1 for it and you also need to add the validator dynamically (so it is not there when the page is loaded, but it appears there during an async postback).

The problem lies in the BaseValidator class itself, after the postback, the validator is not in the Page_Validators array. I've tried rehooking the validators, even enumerating all validators in the page and manually entering them in the Page_Validators array. It does not work. Mainly because the html spans of the validators are not the same thing as the validators and stuff like the id of the control to validate and other details are never rendered.

So you absolutely need to install the .Net 2.0 SP1 in order to use UpdatePanels with validators.
=====

Today I've encountered a strange error, where the validation did work inside an UpdatePanel, but the validator message would not appear. This in a project where I used validation in GridViews inside their own UpdatePanel and they worked!

So I guess part of the reason the error occurs could be any one of these:
  • validated control and validator are both in a UserControl
  • validator is loaded at start of the page, it does not appear during Ajax calls, but it is replaced during Ajax calls
  • validated control is a ListBox, worse, an object inherited from a ListBox


Anyway, the true reason why the validators behaved in this fashion was that they were different from the html node of the validators. In other words, the Javascript array Page_Validators was filled with the validators correctly, did have the evaluation function, did return isvalid=false, but then, when the style.display attribute was changed to inline, the validator was not part of the html page DOM, as it was changed by Ajax.

Solution: a Javascript function that enumerates the validators, gets the validator DOM node by way of document.getElementById, stores the validator properties into this node and then replaces the element in the Page_Validators array.
Problem: where should one load it? Possible solutions include submit button onclick events, form onsubmit events and in the Page_Load method. I would not use onclick, since I should have added onclick events on all possible submit buttons. I would not use RegisterOnSubmitStatement, since it ran the code after checking if the validators are valid or not (even if the validation itself took place afterward; now that is weird). The only solution is to use Page_Load.

There are various ways of doing that, too, since you could use MasterPages, custom made Page objects and even HttpHandlers or HttpModules. You also could have custom controls or objects that don't have a reference to the Ajax ScriptManager object or even to the Ajax library itself. Yes, I know, I am very smart. In my project, all the pages were inherited from a custom Page object, also in the project. So it was relatively easy.

Here is the code:

// in Page_Load
string script=@"
if (typeof(Page_Validators)!='undefined')
for (var i=0; i<Page_Validators.length; i++)
{
// get DOM node
var vld=document.getElementById(Page_Validators[i].id);
if (vld) {
for (var key in Page_Validators[i])
// check if the Page_Validators element has extra attributes
// and add them to the node
if ((vld[key]==null)&&(Page_Validators[i][key]!==null))
vld[key]=Page_Validators[i][key];
// replace the Page_Validators element with the reconstructed validator
Page_Validators[i]=vld;
}
}
"
;
// get current ScriptManager for this page
ScriptManager sm=ScriptManager.GetCurrent(this);
if ((sm!=null)&&(sm.IsInAsyncPostback)) {
// if we did an Ajax postback, fix validators
ScriptManager.RegisterStartupScript(Page, GetType(),"FixValidators",script,true);
}

In order to access an object even after postbacks, you need to put it either in the Session or the ViewState. The ViewState is preserved only between postbacks, not between different pages and it is a Page property, so it is more efficient to use it. The problem with this method is that every object you put in the ViewState must be serializable.
So, the quick and dirty path: if you don't have strange custom serializing to do, all you have to do it to decorate the object with the [Serializable] flag, like this:
[Serializable]
public class MyDictionary StateDict:Dictionary<int,bool> {
}

Say you wouldn't have done this, you would have probably met with the "Class is not marked as Serializable". Duh!. However, in this situation above I have inherited from an object that implements ISerializable. I will get an error "The constructor to deserialize an object of type ... was not found". What that means is that the object must have a constructor that accepts two parameters, a SerializationInfo and a StreamingContext object. So we must add it to the object, like this:
[Serializable]
public class MyDictionary StateDict:Dictionary<int,bool> {

public MyDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { }
public MyDictionary() {}

}

I added the second constructor because when adding a parametrized constructor, the default empty one is no longer inherited. So no more new MyDictionary() unless one adds it.

That does it! Please do check out the entire ISerializable interface documentation, since it requires, besides the constructor, a GetObjectData method, with the same parameters as the constructor, which controls the custom serialization of the object.

and has 0 comments

 Now, you might ask yourself what has the girl in the image with making your own girlfriend. Look closer, it's not a girl (and not a nigth elf either) it's a computer generated image, made from scratch.