Friday, October 27, 2006

Sort datatable with the Select method when column names contain commas

Well, basically, you can't do it.
I am looking at the internal ParseSortString(string sortString) in the DataTable object of NET 1.1, where the first thing the method does is to split the string by commas, then check for square brackets. This insures that there is no way to sort datatables by columns with commas in their names. The funny thing is that the filtering expression is treated like royalty by an ExpressionParser object, and allows column names with commas inside.
Now let's check the code for NET 2.0. It's identical.

The solution is a little annoying code like this:
private DataRow[] SelectSafe(DataTable dt, string filter, string sort)
{
  var columns = new string[dt.Columns.Count];
  for (var c=0; c<dt.Columns.Count; c++)
  {
    columns[c] = dt.Columns[c].ColumnName;
    if (dt.Columns[c].ColumnName.IndexOf(',')>-1)
    {
      dt.Columns[c].ColumnName = dt.Columns[c].ColumnName.Replace(',', ';');
      // assume that the column name was bracketed correctly in the select
      sort = sort.Replace(
        "[" + columns[c] + "]",
        "[" + dt.Columns[c].ColumnName + "]");
    }
  }
  var dr = dt.Select(filter, sort);
  for (int c=0; c<dt.Columns.Count; c++) {
    dt.Columns[c].ColumnName = columns[c];
  }
  return dr;
}


I am sure there is more elegant code, but this seems to be the only solution so far except manually sorting a DataTable.

Wednesday, October 25, 2006

MSDN Briefing Bucharest 24th of October 2006

The whole meeting took place at the Titulescu room at RomExpo. They had 4 desks that spanned the alphabetical ordering of software firms participating, so the entry was really comfortable. They gave us a pen and a little notebook to take notes, too. The whole meeting lasted from 9:00-16:30, then there was an hour of free talks.
My general impression of the briefing was good. The presenters were enthusiastic and talked about: application development on Windows Vista with NET 3.0 and Sharepoint and Office 2007. The new Microsoft XML office format was presented, programatic methods of accessing and creating them, how to mix Sharepoint and Office in order to create quick Excel based web sites, etc. The most interesting part, though, was of course the last. It presented the advances in programming technology like the C# 3.0 features and ADO.Net vNext. Too bad I've already read about those technologies, but the enthusiastic presentation mode (alas, SPOKEN TOO LOUD) was refreshing.
The information was as compacted as possible, but there was too little code for me, even if most presenters seemed to have the same hatred for marketing slides as I did.
There were also 30 minutes of coffee break and 1 hour of lunch. The lunch food was very good and varied, from chinese apetizers like sesame meatballs and Shanghai chicken to sandwiches, salads and sweets. Taking into account that I've been to a similar Microsoft thing in Milano, where they barely gave us some sandwiches in plastic bags, this was truly great.

Monday, October 23, 2006

NullReferenceException in GridView BuildCallbackArgument when trying to render it dynamically with paging

Whoa! Big title there. This article applies to errors in ASP.NET 2.0 when trying to dynamically render a gridview with paging.

I have been trying to "Ajaxify" my web programming and I've found that the easiest method is to wrap everything I need in Web User Controls, render the controls, then send the rendered string through ajax to fill some innerHTML.
Well, the fine people at Microsoft thought otherwise. I have been trying to render a web user control with a gridview inside it for 3 hours now and nothing helped. I kept getting a NullReferenceException when calling GridView.DataBind and the StackTrace showed it originated in the BuildCallBackArgument(int) method.
Nothing helped except actually decompiling the code of the GridView itself. I've found out that it called a method in the Page of the control, in other words it needed a page. I gave it a page, but then another problem occured that I'd already solved here. I already had a parent page that overrode the offending method, so the final code is this:
ParentPage pp=new ParentPage();  // where ParentPage is a Page with VerifyRenderingInServerForm(Control control) overriden so it doesn't do anything
pp.EnableEventValidation = false; //another silly error
uc.Page = pp; //uc is the user control needing rendering
uc.Bind();

Bush in space.

It just had to come. It was inevitable. Bush has signed a "tough space policy" which basically says the US will hold space itself hostage as they do water, air and economy on Earth.
Just read the BBC article and draw your own conclusions. Before they even explore it, the Americans seize space as their own, all in the name of "protecting" their space sattelites or whatever.
So next time you god damned university students want to launch your geek science projects into space, you'd better clear it with Bush. Or Rumsfeld.

Thursday, October 19, 2006

Javascript replace function

Unlike .NET C# (or most other programming languages), the Javascript replace function only replaces the first instance of a string. To replace all the instances, you need to use regular expressions.
Simon Willison's Weblog contains a good article on this.

Basically, if you use str1.replace(str2,str3) it will return str1 with the first occurence of str2 replaced with str3. If you use str1.replace(regexp1,str3) and the regular expression has the g modifier it will return str1 with all matches of regexp1 replaced with str3.

A regular expression looks like : /searchpattern/modifiers.
You can create a regular expression from a string by using the
new RegExp(str2,modifiers)
syntax.

The problem comes when you want to create a regular expression from a variable that may contain regular expression escape sequences. Here is Simon Willison's function that "escapes" the string in order to use the RegExp syntax safely, slightly modified to contain the '^' character:

RegExp.escape = function(text) {
if (!arguments.callee.sRE) {
var specials = [
'/', '.', '*', '+', '?', '<', '>',
'(', ')', '[', ']', '{', '}', '\\', '^'
];
arguments.callee.sRE = new RegExp(
'(\\' + specials.join('\\') + ')', 'g'
);
}
return text.replace(arguments.callee.sRE, '\\$1');
}


Example: str=str.replace(/\\/g,'\\\\') (replace slashes with double slashes)

Wednesday, October 18, 2006

Oh, come on!

'
This is an image from the BBC web site and the title of the BBC article is Rice launches Korea crisis tour and the caption is Japan and the US pledge to work on implementing sanctions on North Korea, the US Secretary of State says.
I knew politicians are assholes, but how can you smile like that while deciding pledging to impose sanctions on some other nation? Look at her! You'd say she's hugging her daughter while petting the cutest cat ever. And she's imposing sanctions! And the title sounds like she has just opened a tourist resort. That whole picture is wrong. Geez!

Tuesday, October 17, 2006

Checking your web app against different browser resolutions

    I have found three basic methods:
  1. Use an online type of viewer.
    You select the resolution, type in the URL of your site, then sit back and relax.
      I see a lot of problems for this method:
    • you don't want everybody to know you are working on a site

    • you don't want the site to be open to the public while you work on it

    • you need an internet connection


  2. Use an external program.
    BrowserSizer is as good as any. It's free and easy to use. You select the resolution and it resizes your IE window accordingly.
    The only problem I see is that you need the program. You install it, it messes with your browser settings, etc.

  3. Use a javascript script in the IE addressbar:
    javascript:db=document.body;bst=db.style.zoom=1;rd=prompt("Width:",800);
    db.style.zoom=db.offsetWidth/rd;void('')

    Unfortunately, the zoom messes up quite a few things, including fixed table headers or custom javascript controls. However, I do believe it is the best solution for most situations.

ASP.NET DefaultButton on LinkButton or ImageButton and Mozilla Firefox

You may experience unexpected results when you open a Web page that is in an ASP.NET 2.0-based application in Mozilla Firefox and the DefaultButton property is assigned to a LinkButton control or an ImageButton control

Just a reminder of a bug I am likely to encounter. The obvious solution is to use ControlAdapters or inheritance to create LinkButtons and ImageButtons that are rendered as buttons.

FxCop - automatic check of NET code.

I've accidentally stumbled upon FxCop, a Microsoft free tool that analyses the generated NET code (.exe or .dll) for bad design practices.
While many of the errors and warnings I got were related to casing, a lot of them were not and they had come with links, extended information and solutions. The rules that FxCop has help you to make members static if none of the instantiated object's properties or members are used in it, use case insensitive String.Compare instead of comparing two ToLower strings, or StringBuilder in loops, use NET 2.0 constructs instead of 1.1 ones, etc.
I find it at least interesting and I intend to use it in my future software projects.

Missing on spam!

I've recently changed my email address, added spam filters both on the server and on the client and moved all known addresses into a special folder, leaving any unknown source (thus mostly spam) emails alone in the inbox folder. This resulted in me not receiving spam email for at least a week. Now I kind of miss it. I mean, I feel something is wrong, like some essential part of my life is gone. How weird is that?
And apparently, I am not alone. 231 pages in Google have "I miss spam" in them.

Thursday, October 12, 2006

Virtualize! Good bye, cruel real world!

ASP.NET 2.0 has this nice feature called Virtual Path Providers. What it
actually does is enable you to get your site files from anywhere using an
override of the VirtualPathProvider class.

Virtualizing Access to Content: Serving Your Web Site from a ZIP File
This is a very nice article where a Microsoft guy shows how to run a
complete ASP.NET site from a ZIP arhive. Just two lines of code in
global.asax , a standard web config file and a ZIP arhive.

This opens up a lot of possibilities, like reading the ASPX or CS files from
a class that creates them dynamically, or reading the files from multiple
sources at once. Yummy!

Tuesday, October 10, 2006

Nullable types in C# 2.0

I vaguely remember reading of nullable types in the C# 2.0 "what's new" documentation, but somehow it slipped by me. Now I've stumbled over this useful new feature and I can explain it for a bit.
Here is the Microsoft explanation.

Basically you can declare any value type as nullable by using the syntax <type>?.
Example: int? x=null;
There is even a nice operator ?? that acts like the SQL isnull function.
Example: int y=x ?? 0;
The two above examples are the short for the following:
System.Nullable x=null;
int y=x==null?0:x.Value; int y=x.HasValue?x.Value:0; OR int y=x.GetValueOrDefault(0)

    The Nullable type has some nice methods:
  • GetValueOrDefault([value]) - gets the default value or the specified value when the nullable type is null

  • HasValue() - something like is not null



There is no IsNull method to the Nullable type. Also, x=null makes x==null true, as opposed to, let's say, the SqlInt32 type.

Monday, October 09, 2006

Thomas Covenant, by Stephen Donaldson

I've just finished The Runes of the Earth, the first in the last series of the Thomas Covenant saga. I must say that the style and content changed significantly from the first books, therefore I felt the need to review the whole saga as I see it now.
I liked that in each book new ideas were introduced, they weren't just reprints of the same story. The moral basically stays the same, but everything else, sometimes even the lead character, changes.
From the second series, a new model of writing was used, thus all the books in one series make out a story rather than one book per story. I didn't like that, especially now, when I have to wait for the next books to be published in order to see what is going on. What I also minded was the need of the characters to shed tears over all kind of stuff. I think the author overdid the misty eyes scenes. A lot of the creatures and the culture from the first series was completely obliterated in the second, but it seems to be making a come back now.
The good thing about it, though, is that the writing gets better with each book. In hindsight, the first book seems amateurish compared with the rest. No more singing, more story, less descriptions. It is interesting that the last series of the Chronicles of Thomas Covenant the Unbeliever was published 20 years from the end of the second. Donaldson justified this as taking time to become a better writer before ending the story.
Let's see how it goes.