A good deal of yesterday and some of this morning I've been fiddling around with nested ASP.NET DataGrids. Binding nested grids is pretty easy and they show all you want, but editing items in a nested grid just doesn't work as easy as editing in a simple Grid. In fact, it doesn't work at all. What happens is that you can put a nested grid into edit mode, but you never seem to be able to catch any Update/Cancel events from the edited item.
I tried to look for a solution by asking Google, but the answers that I found were very unsatisfactory, since there was no explanation on why exactly it doesn't work. So, here's why ... and it's very, very simple: Nested DataGrids lose all of their ViewState on any roundtrip. That seems to be some sort of problem that's actually related to how the entire TemplateControl infrastructure works, but that's what it is.
Since that's the case, the EditItemIndex isn't preserved across the roundtrip and the DataGrid doesn't know how to dispatch the Update event. Now, how do I work around it? Again, pretty simple: You need to store the EditItemIndex (and SelectedItemIndex, etc.) of the nested data-grid in the Page's ViewState whenever they change (Edit event, Cancel event, etc.), keyed by the UniqueID of the DataGrid and a matching suffix. When you reload the sub-grid on a roundtrip, recover the value(s) from the ViewState of the page and DataBind().
I've put the workaround into my current working copy for dasBlog (the OPML editor gets a hierarchical editor now) and it works great. Next build that gets released, you can look at it.
There’s a bit too much advertising in the dasBlog themes. I didn’t remove some of the links that were meant to be only on our themes here at the newtelligence site. The download below is a drop-in replacement for the themes than are in the current build (1.0.3210.0)
Download: themes_1_0_3210_0.zip
After Stephen Forte, who heroically tries to get dasBlog to run on the 1.0 Framework, came back to me with “it’s very slow”, I spent a little time profiling and investigating and it turns out that showing the comment count for every entry is a big problem because of the internal file structure of the underlying BlogX store (it puts comments into an extra file). For the next build, there is going to be a config switch to turn rendering the comment counters on and they will be off by default. We’re talking about a 200%-300% perf gain for the respective execution path on my machine here, so this is a significant improvement. What I also switched off for good (unless anybody complains, in which case it may become switchable) is the ability to include ASP.NET controls straight into the templates, because there is a macro that allows you to pull in web user controls and this should do the job well enough, because the template by themselves allow no additional control over the controls you could inject.
It apparently took Tom Mertens about 5.43 seconds (ok, but not much longer) to get his dasBlog installation working. My site logged his Weblog comment at 18:17 and now at 18:40 he did already switch.
I wish I knew how the GotDotNet workspaces work and more why they don’t
work so often. I get to the workspaces console and when I click to get into the
workspace, nothing works. And it’s not the first time. Or is it me?
So, (t)here it is. And even a day early. I uploaded newtelligence dasBlog 1.0.3210.0
There’s a GotDotNet workspace where you can get the installers (one for a Website and one for the source) or get all source code using the GDN source control “applet” or the VS.NET plug-in.
The files are also available at http://www.dasblog.net/ in the Download section, but GotDotNet is a better choice for bandwidth (for you and for us). If you want to build the source code, you need Visual Studio .NET 2003.
Make sure you read the instructions of the web-install and read the docs that are already there and specifically the docs on the installation steps.
BlogX users should have it very easy to upgrade. Use the web-installer to create a new site on your local machine and drop your existing siteConfig and content directories into the new installation. The siteConfig only needs one new entry in that case: You need to add a <BinariesDir>content/binary/</BinariesDir> tag. The installer should create the necessary subdirectory already. Once the site runs (the setup steps are exactly identical, otherwise and therefore it should) and you’re happy with the templates and all, you can copy the whole stuff over to your existing site and you’re set.
Radio Users will have to fiddle around a bit and poke around in the web.config (see the UrlMapper config section) and look at a previous post to help their hyperlinks to follow them to a new site. Between then and now I made an update that will not only redirect the hyperlinks but also the referrers and I’ll post something about that on the www.dasblog.net site these days. It shouldn’t be too hard to figure it out looking at the UrlMapper config if you are Regex savvy.
However, starting with the content and setting up a replacement for Radio is very easy if you told Radio to make “XML backups” of you data. The command line tool (DasBlogRadioImport.exe) that is included with the source setup and about the only set of files that made it over alive from BlogX, allows you take all the content with you:
dasblogradioimport /from:"c:\program files\radio userland\backups\weblogArchive\posts" /to:c:\temp\radionew
The target directory, which must exist before you run this, will contain a complete content directory that you can simply drop into your new site.
I am not sure about switching from other tools, but since you have a MovebleType/Blogger/MetaWeblog API endpoint sitting at /yoursite/blogger.aspx, some tool may be able to make sense out of that for import/export. I have successfully tested w.bloggar, Zempt and blogBuddy with dasBlog. However, nothing beats Outlook for blogging.
I am not done packing the code yet. (That's really a lie, because I have the installers sitting here, but I am considering some last-minute changes for some file names and don't want to create too much confusion once the stuff is out).
However, I have already put a good deal of the user documentation on the "dogfood" site where dasBlog is used to document dasBlog. I plan to put the downloadable files (one MSI for setting up a web and one to set up a code tree) over there by Wednesday and then I also will start filling in the "Code" section with some guidance on where to find what. The feature I love most is "Mail To Weblog".
This week:
- Ingo Rammer will be 24 on Thursday, if I remember right
- I am going to release DasBlog and throw a lot of source code at everyone ;)
- newtelligence will be 3 years old on Friday
- I will be 34 on Friday
- ... and there's one more thing we're waiting to happen on or before Friday
There's an option in Word to reduce the amount of odd markup Word injects into e-mail when used from Outlook ...
Dave Winer suggests an experiment:
Shall we run an experiment is to see if aggregators can work with RSS feeds that have a xmlns attribute at the top level, on the <rss> element?
... and continues with an example:
<rss version="2.0" xmlns="http://blogs.law.harvard.edu/tech/rss">
Now, the RSS spec doesn't say that this is okay, but neither does it say it's not okay.
Yes, the RSS spec may not but that doesn't matter, because it's just a vocabulary on top of existing specs that take matters a bit more seriously. The XML namespaces spec says: "If the URI reference in a default namespace declaration is empty, then unprefixed elements in the scope of the declaration are not considered to be in any namespace", which is true for all RSS elements as per RSS specification, because it ignores namespaces and is therefore subject to this default case. Therefore, setting a default document namespace like that may be permissible as per RSS spec, but recognizing such a document as valid RSS is just wrong. I would suggest to revise the spec and not to experiment.
Our buddy René Pierre Coburger understood the
obvious name reference and made this little logo for the blog
engine.
This was a fun week, really. Last week I was mostly at home and spent quite a bit of time (on the balcony, in the sun) refactoring BlogX and adding new features "offline". This week I tested and stabilized things using the online version, upgrading to a new build at least twice a day here at the office. I am quite happy with it. It's really cool playing with the stuff now. I think I am going to set up an additional, different blog just to play around with the features. But until now I needed your referrals and pingbacks and so on.
During this week I also thought about the naming issue, because -- as I pointed out before -- there's not much left of the original BlogX code base now and to limit confusion the thing had to get a different name (ChrisAn still gets proper credit in every single source file, of course). I had about two dozen ideas and it turned out that all of them were already taken either by some software or someone's personal blog and I also didn't want to hijack any of these names. So, I went for a very simple (sort-of) German variant: "Das Blog". So, it's "newtelligence DasBlog 1.0" now.
Some time this weekend, my buddy Stephen Forte is going to get a copy (he's the guinea-pig) and if he's happy with it, I'll check the stuff into a new GotDotNet workspace and then additionally post a web installer (that sets up a basic site) and an installer for the source tree by next week.
The feature-delta to BlogX as of now: Rendering using original templates from Radio, Pingback client/server, Trackback client/server, File-uploads, Picture uploads, web-based DTHML editor, Mail-To-Weblog with attachment and embedded pictures support, pick-up of referrals from redirects (from old blogs), mail notifications for pingbacks, trackbacks, and referrals on the permalink, refactored and streamlined access to the backend, safer file handling, subtitles, experimental Atom syndication support, per-item comment RSS files and "some other changes". I think I need force myself to work on documentation now and stop adding features.
Just testing the HTML fix. This should now be
it. 
Testing, testing ... MailToWeblog thread
Three minutes ago I was thinking "Theoretically, this entry should show up on my blog, in the 'Blog' category, in three minutes" and if you can see this, it did actually work.
I just deployed the first iteration of the last bigger chunk of work that I planned to do on the blogging software (for which we found a new name, meanwhile and you can find it at the bottom of the page). I can now send mail to a POP3-account, which the blogging engine watches. It will not only pick up the text, but will also extract and store any embedded pictures and attachments and link them to the entry. If this here works properly on the actual site, the only little thing I still need to do is to clean up the content for "text/html" so that only the stuff between the <body> tags is emitted into the entry.
This is a little document icon, which I added "as picture" in Outlook: 
And here's the footer if it's attached as file:
Download: document.gif
Ingo says that "sealed" classes are a good thing and goes great lengths to explain why he thinks so in this article.
Now, I do have a little problem with his conclusion (which I still partially share, because I do write sealed classes every once in a while, but for a slightly different reason, see below) because the example he's using isn't really fitting the problem and he actually makes some assumptions about the ImageList class that aren't accurate in this context.
First off, the property ImageList.Images isn't virtual and therefore cannot be overridden, at all. So that by itself is no reason to make the class sealed. The property has been introduced by the class, the class designer chose not to make it virtual. Can't be overriden, done. The same is true for all other properties except Container and Site, which are inherited from System.ComponentModel.Component. I fail to see anything on the ImageList class (not even a method) that really justifies the lockup using sealed considering the current version of the Framework. The bad that sealed does here is that I can't create a wrapper around the ImageList that simplifies setting up such a list in my specific environment.
Using sealed on a class is a very brutal thing to do. A more gentle way of using the sealed keyword is to say [void sealed override myMethod() { }], which essentially says: "Within my own class space I am using inheritance for this method, but since outsiders don't know what I am doing I won't let them override the behavior from here downwards in the class hierarchy." That doesn't affect the inheritability of the entire class and hence doesn't adversely affect the ability to wrap the existing functionality.
Now ... is sealed on a class just plain evil? There are two answers:
- Yes. The keyword sealed on a class usually doesn't have much or any of a technical justification in the "here and now" version of a class library.
- No. The keyword sealed conveys a very clear message that the class designer reserves the right to change the class so dramatically in a future release of the product that you would be tremendously unhappy if you had derived from it to implement your own functionality, once that new version comes along. Sealed says: This is going to change in a big way.
The UDDI OPML list is now being cached in memory and refreshed every three minutes on a background thread. Unless the AppDomain recycles, the responses should be instantaneous now, unless you are doing a query on categories, because that needs to happen live because I don't want to cache each and every request combination on our server here and have it take up too much memory for this demo.
I looked at IBM's UDDI service yesterday and at least the web interface is by several magnitudes quicker (from here). I should probably play with their service a little to improve response times. ( ... just did, IBM and SAP aren't any faster)
|