Ruminations of J.net idle rants and ramblings of a code monkey

Moving from dasBlog to BlogEngine.NET

BlogEngine.NET | Web (and ASP.NET) Stuff
As I mentioned previously, I’ve moved from dasBlog to BlogEngine.NET for this blog. This, of course, involved reformatting and redesigning the look and feel of the site; that’s nothing unique to the migration and I’m not going to go into that at all. What I will do, however, is discuss the process of moving existing content over from dasBlog to BlogEngine, something that isn’t really hard but does have a few gotchas. Moving the Content That’s the first thing that needs to be done. In fact, I did this before I even started formatting the new site – I wanted to be sure that the existing content rendered relatively well in the new design. It was not quite as simple as described on Merill’s blog. All of his steps are valid, but there is actually a couple of other things that need to be done. You will definitely want to use the dasBlog to BlogML Converter that Merill posted on MSDN Code Gallery – dasBlog doesn’t do BlogML and, while BlogEngine will import RSS, RSS usually will not get all of your content. BlogML works much better. There were two things with moving the content … how big a deal those are depend on how picky you are about the move. I was. First, the timestamp on the entry. dasBlog uses UTC (GMT) to store the time and that’s how it is imported into BlogML. BlogEngine uses the server time. Both have an offset to convert the saved time into blog local time, but dasBlog’s offset is from UTC (using standard time zones) and BlogEngine uses an offset from the server time. My server is on US Eastern Time and my local blog time is US Central Time, which means that, on import, I had to convert the time to US Eastern and then set my offset in BlogEngine to –1 (US Central is 1 hour “behind” US Eastern). To do this, I had to modify the code that imported the blog entries, which can be found at BlogEngine.Web\api\BlogImporter.asmx. Since the incoming BlogML only had a post date, not a DateCreated and a DateModified (as BlogEngine does), I also set both the create date and the modify date to the same value. Here’s the code snippet from AddPost: Post post = new Post(); post.Title = import.Title; post.Author = import.Author; post.DateCreated = import.PostDate.AddHours(-5); post.DateModified = import.PostDate.AddHours(-5); post.Content = import.Content; post.Description = import.Description; post.IsPublished = import.Publish; Once I set BlogEngine’s server time offset (in the admin section under “Settings”), all of the times were now correctly displayed as US Central. The second thing relates to the tags … BE uses tags (and categories) while dasBlog only uses categories. In dasBlog, the “tag cloud” is generated from the categories and BE generates this from the actual post tags. I can’t say which method I like better yet or if I prefer some mish-mash of the two (generate the cloud from tags and categories … that may be an idea) but I did know that I didn’t want to lose my tag cloud. So, on import, I added tags for each post category to the imported post. Again, simple and again, in AddPost: if (import.Tags.Count == 0) { post.Tags.AddRange(import.Categories); } else { post.Tags.AddRange(import.Tags); } From a performance standpoint, I couldn’t tell you if AddRange is faster than looping block to add each value individually (and it really doesn’t matter here), but it is simpler, cleaner and much easier to read … so I tend to prefer AddRange(). With these two “issues” resolved – and they aren’t issues with BE, to be sure, just a difference between the two – I was ready to move on. Preserving links Some of my entries have a pretty good page rank on various search engines and there is a non-trivial amount of traffic that is generated from these search engines. While I can go in and change things like the RSS source for my feed from FeedBurner to make the move transparent, that doesn’t help with the search engines. Therefore, I needed a way to ensure that existing links would continue to work without returning 404’s. Yes, I moved the old domain over to the new domain and added it as a host header on the new site, but that does not help prevent link breakage and BE and dasBlog have different formats for their links. I also did not, at this point in time, want to force a redirect as soon as a new person hit my site from a search engine; it’s just rude (IMHO) and doesn’t create a great user experience. Sure, maybe it wouldn’t be a big deal, but I didn’t like it. And besides, it gave me an excuse to write code. :-) To keep the links intact, I decided that I would leave BlogEngine’s UrlRewriting intact; I didn’t want to make too many changes to the base source code as it would make it harder for me to move between versions/revisions. Rather, I wanted to sit on top of it and make sure that the links worked. So I used ASP.NET Url Routing to intercept the requests and send them to the right place (post.aspx). Before I go into the code, let’s first examine the (default) url structures for individual posts. In dasBlog, the post link is in the format yyyy/mm/dd/{CompressedTitle}. In BlogEngine, this would be post/{CompressedTitle} –or- (the permalink format) post.aspx?id={PostGUID}. While BE can have the date as a part of the post link, it still wouldn’t work; they compress their titles differently and, as mentioned before, dasBlog uses UTC internally and it’s used in the link as well. For the routing, I created the route using "{Y}/{M}/{D}/{Title}" as the route url. From there, I needed to implement GetHttpHandler to do the work. Initially, I did the matching to title using a Linq query and it worked just fine. The problem with this is that every title in the posts would need to be converted to the dasBlog format (I copied over the dasBlog CompressTitle method as dasBlogCompressTitle), a process that seemed far from ideal. Once I understood how the dates worked, I was able to do the primary matching on the date and then, if necessary, match the titles for posts on the same date, minimizing the string manipulation that was required. Once I determined what the matching post was, all I needed to do was append the query string “?id={postGuid}” to the URL and then pass back the HttpHandler from post.aspx for the actually processing. If there was no match, then there would be no query string appended and post.aspx would show a 404. The code for this is below: public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext) { //Get the date from the route. string dateString = string.Format(@"{0}/{1}/{2}", requestContext.RouteData.Values["M"], requestContext.RouteData.Values["D"], requestContext.RouteData.Values["Y"]); string titleString = ((string)requestContext.RouteData.Values["Title"]).Replace(".aspx", ""); DateTime postDate = DateTime.MaxValue; Post selectedPost = null; if (DateTime.TryParse(dateString, out postDate)) { //Date is valid at least. //Find posts with the same date. //Date in URL is in UTC. var postsForTitle = from p in Post.Posts where p.DateCreated.ToUniversalTime().Date == postDate select p; if (postsForTitle.Count() == 1) { //There is only one posts for the date, so this must be it. selectedPost = postsForTitle.First(); } else { //differentiate on title. foreach (var p in postsForTitle) { if (dasBlogCompressTitle(p.Title).Equals(titleString, StringComparison.InvariantCultureIgnoreCase)) { selectedPost = p; break; } } } if (selectedPost != null) { //Use UrlRewriting to put the id of the post in the query string. requestContext.HttpContext.RewritePath(requestContext.HttpContext.Request.Path + "?id=" + selectedPost.Id.ToString(), false); } } return BuildManager.CreateInstanceFromVirtualPath( "~/post.aspx", typeof(System.Web.UI.Page)) as System.Web.IHttpHandler; } Once I set it up on the web.config file and added the routes to the RouteTable, all was good and it worked fine. Preserving the RSS Feed Url The final step - and the thing that occurred to me last – was to make sure that the RSS feed url continued to work. While FeedBurner had no problem with changes the RSS url for my blog, there was the possibility (however remote it may have seemed) that someone was using the dasBlog’s RSS feed rather than FeedBurner. I’m not sure how remote a possibility this is but I didn’t use FeedBurner in the early days of the blog, so I figured that it might be an issue. And I certainly wouldn’t want to alienate the longest-time subscribers to my feed. This was incredibly simple and didn’t require any code at all, just two lines line in the web.config file to have SyndicationService.asmx (dasBlog’s RSS feed) handled by BlogEngine’s RSS feed, which is implemented as an HttpHandler and, by default, at syndication.axd. The first line is for IIS 6.0/IIS 7.0 Classic mode and is under the httpHandlers node of system.web: <add verb="*" path="SyndicationService.asmx" type="BlogEngine.Core.Web.HttpHandlers.SyndicationHandler, BlogEngine.Core" validate="false"/ The second goes in the corresponding location for IIS 7 Pipeline mode, in the handlers node of system.webServer: <add name="dasBlogSyndication" verb="*" path="SyndicationService.asmx" type="BlogEngine.Core.Web.HttpHandlers.SyndicationHandler, BlogEngine.Core" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode"/> These were copied from the default nodes used by BlogEngine for it’s syndication.axd and then the relevant attributes were changed. Simple enough.

Favorite .NET OSS Projects?

Open Source
I’ve just gotten back from the 2009 MVP Summit (it was awesome!) and got into a lot of conversations around .NET Open Source, something that I’ve had a soft spot for ever since getting involved with the original Commerce Starter Kit with Rob Conery. And it’s occurred to me that there is no “list” of cool .NET Open Source projects out there. Yes, there is CodePlex, Google Code, SourceForge, etc. that are repositories of OSS projects … but it’s really somewhat impossible to compile a list from there. And Microsoft (DPE included) has done a less-then-stellar job evangelizing these projects. So … I’ve decided that I’m going to go about making such a list and I’m asking y’all to leave feedback/comments/messages for me about your favorite .NET based OSS projects. Yes, I have my own personal list, but I know it’s not complete … there’s just so much out there. Now, to be sure, there will be some qualifications for the list. I’m still pondering what some of these will be but, I have to say, I’m not leaning towards things like “usefulness”, “quality” or any other equally subjective criteria. Number of downloads isn’t a qualifier either … some OSS projects have been around for a while and/or have a broad applicability (and a lot of downloads) but that doesn’t mean that other OSS projects that fill a more “niche” need (and have fewer downloads) aren’t equally as valuable. BUT … there are some things that I know that I’ll be looking for. So, here they are: Community-driven: This means that those Microsoft-led projects don’t count. I want the projects that are started, developed and driven by the community. This isn’t to say that you can’t have Microsoft contributors on the project but Microsoft should NOT drive the project. Actively under development: There are a lot of OSS projects out there that are simply dead on the vine. Maybe they have a release and nothing else, maybe they never got past “alpha” or “beta” stage. Not looking for these at all. I’m looking for living, breathing projects with an active community. And I’m looking for at least 1 non-alpha/beta release within the past 12-18 months. Link to project site: Yes, I am perfectly capable of doing a search on Windows Live Search (you really didn’t think I’d use the G-word, did you?), but I don’t want to have to go digging around. If it’s one of your favorite kewl .NET OSS projects, you should already have a link, right? So send it to me. And no, it doesn’t have to be on CodePlex and not being on CodePlex won’t count against the project. More details: Tell me why you think that this is a cool OSS project. What need does it fill? How is it unique? What makes it interesting? I’m not looking for a book here, just a couple of sentences will do. But don’t send me a title and/or a link only.

CSK 3.0 CTP1

CSK | Open Source | Web (and ASP.NET) Stuff
I know, I know, it’s a little late. I said Nov 1st and it’s now Nov 3rd. Here’s what happened – I was all on track to have it ready for the 1st, but then I got sick. I felt like a bowl of cold oatmeal, which is not very good. Kids … I’m tellin’ ya … they’re germ factories. I wound up spending the weekend in bed, resting. I could have down a drop on Friday or Saturday regardless, but it wasn’t at the point that I wanted it to be. Now that I’m feeling better, I got back down to it and got it to the point that I wanted in about an hour or so worth of work (told you I was close). [EDIT] You can download it from CodePlex. (thanks Alan!) Release Notes This is a Tech Preview. Read: nowhere near final. It’s not even up to what I’d call a beta. I’m putting this up primarily for feedback from the community and (hopefully) to generate some additional interest. It does show the direction that I’m going with this and I hope you’ll notice that, while the underlying functionality is pretty complex, it’s easy to work with and easy to change the UI. I have avoided duplicated any code as much as possible, though I may have missed something. User Interface elements: Most of the user interface is encapsulated in User Controls, which you will find in the Controls folder. I think that the names should be self-explanatory. For simplicity, data binding is used whenever feasible. Yes, it is not the most attractive. If there is anyone with better design skills, I’d be happy to hear from you. Implemented functionality: It’s the very base functionality; you have catalog display and navigation, cart functionality and checkout functionality. Checkout does not, at this time, call any of the payment processing components but the code will be (for the most part) the same when that does get added in. Installation: Unzip the file to a folder on your system. In the Data folder, you will find a backup of the Sql Server database that is used for the site. If you restore this to “.\SqlExpress” in a database named “CommerceDb”, you will not need to make any changes at all to the connection strings. If, however, your database is different, change the connection strings that are in the web.config. Coming next: Added actual payment processing. Would like to get login implemented as well; we’ll see about that.

CSK 3.0 Current Status

CSK | Open Source
Just last Friday, Rob Conery and I announced that we were working on a Commerce Starter Kit v 3.0, reviving the spirit of the CSK - “Sell your stuff, not your soul” (I always loved that tag line!). The project will be hosted on CodePlex. The current 3.0 checkins do not represent the current state of affairs, but a very interim state. It does show the architectural direction though. I also packaged up the final release of CSK 2.0 that Rob and I collaborated on so long ago for those that are interested. CSK 2.0 will not be actively supported moving forward. Support for CSK 3.0 will be done on the ASP.NET Forums. This is a quick update on the current status and a preliminary schedule for releases, etc. Keep in mind that this is preliminary and subject to change (in either direction). November 1, 2008: First drop of CSK 3.0. We’ll call this one a “Community Tech Preview” (CTP) and, in the tradition of CTP’s, it will represent a work very much in progress. We should have all of the major UI components of the site in place and, to some extent, functional. Well, catalog and cart are functional now, checkout … that may not be quite there on Friday’s drop, but I hope to have it there. I’d rather have this CTP release sooner than later to get feedback and participation from the community as early in the process as possible. December 1, 2008: CSK 3.0 Beta 1. This will be a stable release and we’re targeting to have it feature-complete. But we’ll still be working on any bugs and tightening down the hatches. January 5, 2009: CSK 3.0 Beta 2. Final beta of CSK 3.0. Again, a stable release, feature complete with few bugs (hopefully) left so we can concentrate on performance tuning and the like. (Note: there will be some tuning throughout the process, but this will involved a major push on tuning.) February 1, 2009: CSK 3.0 RTM. ‘Nuff said. I would love for this schedule to actually be too conservative. I really think it is. But … there’s lots to do and I do have other stuff on my plate as well, so I’m playing it safe. In between these milestones, there will be other drops as work progresses, with at least 1 interim release in between the dates here. If you are interested in working on CSK 3.0 and can commit to spending some time on it (that second part is the hard one!), let me know. This is especially true if you have features that you’d like to see implemented; that’s the best way to get those features in there! Keep in mind though that, much as I would like to, I won’t be giving everyone commit rights … I will need to see some contributions, etc. first. The reality is that we can’t have a free-for-all on the source tree; that would be bad for everyone involved.

Commerce Starter Kit 3.0 &ndash; CSK Reprise

CSK | Open Source | Web (and ASP.NET) Stuff
I am happy to announce a new Commerce Starter Kit. We’re calling it CSK 3.0, but it’s not based on the previous (CSK 2.0) codebase at all; it is a complete re-write from the ground up. Some of you probably remember when I first got involved in the CSK … that was WAAAAAY back in the days when ASP.NET 2.0 was all new and shiny. ASP.NET has, of course, moved forward quite a bit since then. We won’t be just upgrading the old CSK code base, but building a brand-spanking-new version, even though we’ll be calling it CSK 3.0. And … it will be in the same spirit as CSK - “shared source” and freely available to all. I will be reporting progress on this regularly, so you will want to subscribe if you want all the latest updates and news on the project. This all started with a chat or two with my old buddy Rob Conery, the creator of the original Commerce Starter Kit. He’s here at Microsoft now and working on the MVC Storefront, a sample application that uses the ASP.NET MVC Framework (as the name implies). At the end of these chats, we thought we’d revive the CSK name and build a new version … with components and business logic based on the same components and business logic used for MVC Storefront but with a traditional WebForms UI. That’s right folks … it’s gonna share code with the site that Rob’s working on. Not only does it make life much easier, it also shows how the same core logic and functionality can be skinned with either MVC or WebForms. Here’s the core stuff that is on the plate for this version: Updates to the latest coolness: CSK 3.0 will be targeting ASP.NET 3.5 with SP1, so we’ll have all of the latest toys, including (of course!) Linq. :-) Migration to common e-Commerce libraries: I mentioned this above; CSK will be using the same core business libraries and database as MVC Storefront, allowing you to easily switch between the two. Localization support: Oh boy, I remember lots of folks asking for this with CSK 1.x and 2.0. The new CSK will be localizable out of the box. All of the product and category text and descriptions will be localizable. The goal is to also have most, if not all, of the static text on the pages localizable as well. That’ll be fun with resource files. ASP.NET Dynamic Data Administration: The admin site will now be a separate web application so that there’s better isolation from the main web site. Of course, this could be installed as a virtual directory application under the main site but that won’t be necessary at all. You’ll easily be able to deploy it as a completely separate web site. ASP.NET Web Application: This is the “old” (as in 1.x) model for web applications. While it’s not as easily changed while running (since you actually have to do a build), it does provide better start-up performance, something that became a complaint with CSK 2.0. Yes, yes, you could pre-compile the site (and I often suggested that folks do this) but with the web application model, that won’t be a separate step. ASP.NET Ajax: This is all a part of the cool new toys, but I thought I’d highlight it separately. We’ll be using ASP.NET Ajax where it makes sense as well as the ASP.NET Ajax Control Toolkit. Better composability: One of the things that I thought we could have done better with CSK 2.0 was to have a better composition model for the UI … for example, there were 2 or 3 different places to change a product list display … category list, search list, etc. This made it more difficult to maintain as fields were added or changes were made to certain core UI elements. These components will be separated into a series of User Controls, each with distinct, composable functionality. You want to change the view of a product in a list? Change it once and you’ll see it everywhere … search results, category listing, cart, etc. Coupons: This was only partially implemented in CSK 2. Rob and I spent a couple of hours, both on the phone and over IM, and forth on how this would be implemented and I think it’s settled. The coupon system is going to be very extensible so that you can create any type of coupon that your heart desires. We’ll be including a couple of simple ones to get you started. One of my key goals with this rev is simplicity. I want the UI (at least) to be as simple as possible … and I want it to be simple to re-skin the CSK to your own look and feel. To that end, I am using quite a bit more controls and data binding than were used in version 2.0 … everything, in fact, is in some sort of control or another. Additionally, I do want to highlight, as much as possible, the infrastructure of ASP.NET as well as the extensibility of this infrastructure. For example, for the category listing, I’m using a SiteMapProvider that builds a site map from the categories in the database. Believe it or not, this is actually quite easy to do and provides things like the SiteMapPath, which I do plan on getting in there. I will need some help with this – in particular, I’d really like help with the following: Functionality – what features are essential and/or cool? What do you want to see in there? (No guarantees that it’ll make it, but if you offer to do it, it’s a lot more likely!) Design – Right now, I’m just stealing the design and layout from the MVC Storefront, converting it to use WebForms (so no MVC calls), etc. etc. etc. I call it the CASE methodology – Copy Always, Steal Everything. Now, I have the design skills of a dead toad, so redoing the design is simply out of the question. BUT … I would like to see it begin to diverge from MVC Storefront’s look. So any help that you might want to provide to do that would be very nice. Testing – Yes, we’ll have automated tests to catch a bunch of stuff, but manual testing and feedback is also needed, particularly when it comes to user experience. Migration – From CSK 2. I really don’t know if this is going to actually be possible and it’s certainly not something that I have on the list of “stuff to do” but if someone wants to volunteer to write a migration utility, that’d be cool with me. I’m targeting to get the first, alpha “preview” version out in the next week or so and I’ll announce that here as well.

Welcome Rob Conery to Microsoft!

.NET Stuff | Web (and ASP.NET) Stuff | Open Source
I just got a little message from my old buddy Rob Conery ... he's been hired by Microsoft (the ASP.NET team in fact) to work on SubSonic ... a tool that builds an object-centric DAL for you. It's cool stuff ... I've played with it a bit and even though I'm a little leery of code generation tools (call me old fashioned), it's good stuff.  You can customize the templates if ya want and add to the generated DAL pretty easily.  Rob was also the instigator for the Commerce Starter Kit ... now dashCommerce and I've worked with him on that as well.  So ... welcome to Microsoft Rob!  It's good to have ya on board!

My First CodePlex Project

Open Source
No, not the first one I've been involved with, but the first one that I started.  You can find it here: http://www.codeplex.com/BITSDownloadMgr.  It's call BITS Download Manager.  It was a tool that I wrote some time ago to download large files over a VPN connection and have shared it inside of Microsoft for a couple of years as "JarJar BITS" (don't ask).  As the name implies, it uses BITS (Background Intelligent Transfer Service) to do the downloads.  This gives you network-friendly resumable file copies ... definitely better than Windows Explorer.  Wrapping the BITS API in .NET was something of a challenge.  I didn't use TLBIMP because the RCW that it generated was somewhat "messy" (gets and sets instead of properties, whacked data types and marshalling, etc) ... it seems that the BITS API isn't very friendly with that tool.  So I used the hand-crafted RCW from the original App Updater block and made additional modifications to it for newer revs of BITS, added the event callback support and did a bit "cleaning up" some of the marshalling.  There are also disposable wrapper classes around the native COM objects to ensure that they get cleaned up. Things on the list that I want to do: Multi-threaded folder search for the folder copy job Splitting large folder copies into multiple BITS jobs (BITS has a practical limitation of about 100 files per job) New UI based on WPF Additional job creator plug-ins.  Would like HTTP and SharePoint document library jobs. Possibly look into an upload job as well.  If you are interested in helping out, sign up and join the project. 

OSI Approves CodePlex Licenses

Open Source
Well, it's official ... the Open Source licenses that we've been promoting on CodePlex are now officially Open Source approved.  OSI just announced that they have approved 2 open source licenses ... the Microsoft Permissive License (Ms-PL) and is now called Microsoft Public License and the Microsoft Reciprocal License (Ms-RL) (this one had a different name before, but I've forgotten it).  What's the difference between the licenses?  Well, you could, of course, read them yourself ... but I'll be nice and let you know what it is.  Ms-PL: Basically, here it is.  You can use it for what you want, including derivative works.  If you distribute it, ya gotta keep the copyrights in place.  If you distribute it as source, ya gotta do it under a compliant license.  Ms-RL: Similar to the Ms-PL, but includes that you have to include the source code (whether distributed as binary or not) when you distribute any file from the project.  Note that it's just the file that you included ... nothing else.  So ... any improvements or unique cool stuff you've done in a derivative work would appear to be yours.  Both are "as-is" ... take it, use it ...  but don't blame us if it messes up.  Now ... one last thing ... I'm not a lawyer.  I don't pretend to be.  So don't take this as legal advice, blah blah blah.  Talk to a lawyer for the final word, OK?  And don't ask me to pay for it either.