Windows Live Writer and BlogEngine.NET: Can't view Properties

December 14, 2008 10:52

If you're using Windows Live Writer (WLW) and BlogEngine.NET and you find yourself unable to view properties or set tags on your blog posts (like I couldn't do up until just a little while ago), your site is probably missing the "wlwmanifest.xml" file. This file comes standard with the BlogEngine.NET 1.4 release.

For some reason, when I recently upgraded my site from 1.3 to 1.4.5 I missed copying this file into my web site's root folder. The result was that I was missing out on some of WLW's functionality.

Copying the file over is easy enough. It goes in the root of your site.

Much better. Now I can add tags (keywords) from within WLW:

image

Also, I get some extra features where I can view my current tag cloud and access some of management features directly from WLW:

image

I thought I'd look a little further and see what exactly the wlwmanifest.xml file is all about.

The wlwmanifest.xml file is a set of meta-data used as inputs into WLW's metaweblog API. The API is a standard set of functions that allows weblog content tools like WLW to know about what functionality a particular blogging platform supports.

From this MSDN article, WLW will look for the wlwmanifest.xml file in the web site's root when you add a new web site (weblog) or when updating one in WLW. If it can't find it there, it cracks open the default home page and examines the <head> section for a <link…> that might point it in the right direction.

Let's take a look at the contents of the wlwmanifest.xml file:

   1: <?xml version="1.0" encoding="utf-8" ?> 
   2: <manifest xmlns="http://schemas.microsoft.com/wlw/manifest/weblog">
   3:   <options>
   4:     <clientType>Metaweblog</clientType>
   5:     <supportsEmbeds>Yes</supportsEmbeds>
   6:       <supportsKeywords>Yes</supportsKeywords>
   7:       <supportsNewCategories>Yes</supportsNewCategories>
   8:       <supportsNewCategoriesInline>Yes</supportsNewCategoriesInline>
   9:       <supportsCommentPolicy>Yes</supportsCommentPolicy>
  10:       <supportsSlug>Yes</supportsSlug>
  11:       <supportsExcerpt>Yes</supportsExcerpt>
  12:       <supportsPages>Yes</supportsPages>
  13:       <supportsPageParent>Yes</supportsPageParent>
  14:     <supportsAuthor>Yes</supportsAuthor>
  15:     <requiresHtmlTitles>No</requiresHtmlTitles>
  16: </options>
  17:   <weblog>
  18:     <ServiceName>BlogEngine.NET</ServiceName>
  19:     <imageUrl>pics/wrenchicon16.png</imageUrl>
  20:     <watermarkImageUrl>pics/wrench84watermark.png</watermarkImageUrl>
  21:     <homepageLinkText>View your blog</homepageLinkText>
  22:     <adminLinkText>Manage your blog</adminLinkText>  
  23:     <adminUrl><![CDATA[{blog-homepage-url}login.aspx]]></adminUrl>
  24:   </weblog>
  25:   <buttons>
  26:     <button>
  27:       <id>2</id>
  28:       <text>Tags</text>
  29:       <imageUrl>pics/benTag24.png</imageUrl>
  30:       <contentUrl><![CDATA[ 
  31:          {blog-homepage-url}api/tagminiview.aspx
  32:       ]]></contentUrl>
  33:       <contentDisplaySize>250,250</contentDisplaySize>
  34:     </button>     
  35:   </buttons>
  36: </manifest>

You can see a number of tags that begin with "<supports…". These are simply telling WLW that BlogEngine.NET supports these functions and that it should make them available through its interface.

There's also some tags directly associated with identifying BlogEngine.NET as the blogging service as well as the mini-tag application written by Al Nyveldt.

In the end, all I really wanted was to be able to set tags while within WLW. Functionality restored.


How to sort BlogEngine.NET's Blogroll

December 11, 2008 18:57

BlogEngine.NET comes with a nice blogroll control. Here's what mine looks like:

image

One thing I don't like about it is that the entries are not sorted. If you're using XML as your underlying data store, you'll find your blogroll entries in the "blogroll.xml" file. It's easy enough to sort this file manually as long as you only have a handful of blogroll items, but clearly that's not the best, long-term solution.

Instead, I'm going to show how to modify the Blogroll.cs control to automatically sort your blogroll items prior to display. You can download the modified Blogroll.cs file at the bottom of this post.

I had a number of approaches in mind before undertaking this task. The one thing I really wanted to stick to was to avoid changing the existing Blogroll class. I found during my recent upgrade to BlogEngine.NET 1.4.5 that it's best to not mess with the stock items. So, with that in mind, here's some of the ideas I tried (and the reasons they didn't work):

1. Extend the existing control with a control of my own.

Unfortunately this did not go so well. The Blogroll class is locked down pretty tight, with plenty of "private" access modifiers to work around. I could change these to "protected", but that sort of defeats the purpose of leaving the existing class intact.

2. Delete the existing Blogroll.cs and substitute it with my own "ItsCodingTimeBlogroll.cs"

I thought this was the next best thing, but I was quickly foiled by all of the dependencies that remained to the old Blogroll.cs. This makes sense considering Blogroll.cs is a core class of the BlogEngine.NET product.

3. Just modify Blogroll.cs

The changes were fairly minor, so, given the above roadblocks, I decided to go this route. I don't particularly like this approach (I would have liked to have gone with option #1), but the BlogEngine.NET team did not make this real easy, IMHO.

There are probably other approaches, but those are the ones which came to mind immediately.

In the end, using idea #3 above, this is what I did:

1. In Blogroll.cs (in App_Code\Controls) add a new method called "SortBlogs"

   1: private void SortBlogs () 
   2: { 
   3:     try 
   4:     { 
   5:         ArrayList.Adapter (_Items).Sort (); 
   6:     } 
   7:     catch (Exception) 
   8:     { 
   9:         // log error if you like 
  10:     }
  11:  
  12:     return; 
  13: }

2. Add a call to the new method in "CreateList()"

I added "SortBlogs()" as the last step in the "if File.Exists (fileName)" section, like:

image

3. Inherit RssItem from IComparable

Now, locate the "RssItem" class. Inherit from "IComparable":

   1: private class RssItem : IComparable
   2: {
   3:     ...

4. Add a CompareTo method

Add a new method, "CompareTo", to the "RssItem" class:

   1: public int CompareTo (object obj) 
   2: { 
   3:     if (obj is RssItem) 
   4:     { 
   5:         RssItem rssItem = (RssItem) obj; 
   6:     
   7:         return (this.Name.CompareTo (rssItem.Name)); // sort by "Name" 
   8:     }
   9:     throw new ArgumentException (
  10:         string.Format ("Cannot compare RssItem to {0}",
  11:         obj.GetType().ToString ())
  12:     ); 
  13: }

Note that I'm sorting on the "Name" field. You can sort on any of the field names in the XML file, but "Name" seemed the most intuitive.

5. Deploy Blogroll.cs to your web site

Copy Blogroll.cs out to your "App_Code\controls" folder on your web site.

6. Verify

You should have a sorted Blogroll now:

image

Download: Blogroll.zip.

Source(s): I Think, Therefore I Code: How to sort a generic IList<T>


How to upgrade BlogEngine.NET 1.3 to 1.4.5

December 10, 2008 18:29

BlogEngine.NET is an open source blogging platform on which I run both my blogs (this one and the other one). Whereas this blog has the benefit of being based on BlogEngine.NET 1.4.5 from conception, my other blog has been around a little longer and so got its start on version 1.3. I've been meaning to update it to the latest version for a while; this guide will document that process. If all goes smoothly, this step-by-step approach should mirror Al Nyveldt's excellent BlogEngine.NET 1.4 Upgrade Guide. If not… well, we'll see how it goes and hopefully come up with solutions for whatever problems arise.

 

The Steps

1.) Make a backup of your web site

It's a good idea to have a "back out" plan in case something goes wrong or you back yourself into a corner (or run off a cliff). Make a backup now. You'll be thankful you did.

I copied everything from my site to a new, local folder called "BlogEngine.NET 1.3 (backup)". This way it's there in its own separate folder, ready to get copied back to my web server if necessary.

2.) Download BlogEngine.NET 1.4.5

You can get the latest and greatest version of BlogEngine.NET here. As of this blog post (and as the title denotes), version 1.4.5 is the current release. At minimum, you'll need the web site zip. I also downloaded the latest source (core) zip; I like to keep a copy of it around in case I need to make any tweaks. It's open source, remember.

3.) Unzip the web site files into a new folder

Unzip the web site zip into a new folder. This is going to be your new 1.4.5 web site. I wouldn't recommend overlaying it on top of your existing files. Keep it separate. Save yourself some headaches. Remember, we want an easy back-out path in case things don't go so well. If you leave your old structure intact, no harm done.

4.) Remove the "read-only" attribute

Right-click on your new folder, select "Properties", and remove the "read-only" attribute from all files and sub-folders.

5.) Copy "App_Data" from your current web site to your new one

You want to use the new 1.4.5 folders and files in your site while retaining your existing data. To that end, copy the contents of your current "App_Data" folder (you can get it from the backup you made in step 1) into the App_Data folder of the 1.4.5 web site. Don't delete the contents of the new 1.4.5 App_Data folder first; there are folders and files in 1.4.5 not in 1.3 that we want to keep.

6.) Copy user controls & other "stuff"

If you're like me, you've written some of your own user controls, maybe tweaked your favorite theme, or even modified some of the BlogEngine.NET web controls. This is your opportunity to carry all that stuff forward.

Copy each of the following:

a.) User Controls

Copy any user controls you wrote yourself, borrowed from other people, or tweaked your 1.3 "User controls" folder into the new 1.4.5 site's "User controls" folder. The default 1.4.5 site only comes with two: CommentView and PostList. A quick file comparison shows that these have been updated from 1.3, so leave those alone and just copy in your own.

b.) App_Code controls

Similar to user controls, I also tweaked some of the controls found at "App_Code\controls". Copy any you made changes to into the "controls" folder under the 1.4.5 site's "App_Code" directory.

c.) Admin Pages

I also had created some admin pages of my own. These are stored in "admin\pages". If you have any beyond the defaults, copy those to your new site folder.

d.) pics & images

This is getting a little messy, but it looks like I also have some of my own additions to the "Pics" folder, which exists outside the App_Data location. In addition, I have an "images" folder. If you have your own pics, images, or anything else, copy them over. Consolidation of these folders is getting added to my "to do" list.

e.) themes

I also made quite a few changes to my theme of choice (the "standard" theme). Mostly small tweaks to get the right look and feel I was after, but enough that I also copied over my modified standard theme on top of the existing one.

7.) Open the web site project

I'm using Visual Studio 2008, but prior versions should work. You can open the web site project itself or add it to an existing solution. I took the latter approach. When faced with this dialog:

image

I selected "Yes". Al Nyveldt recommended selecting "No", but I use controls from the AJAX Control Toolkit 3.5 in my site, so I need .NET 3.5.

NOTE: Allowing the site to be updated to .NET 3.5 did not seem to have any adverse side-effects.

8.) Build and run it

At this point you should be able to build the web site and run it. I got lucky: no errors or warnings. Even better, the site came up and looks exactly the way I expected.

9.) Use an encrypted password

If you aren't already using a custom provider to encrypt your password, or if you just want to switch over to the default BlogEngine.NET encryption, open up your "users.xml" file in the App_Data folder. Previous versions of BlogEngine.NET saved your password as clear text. While that's been a major point of contention in the past, it's fixed now.

If you see your password in clear text in the users.xml file, Al recommends blanking it out:

image

Al then recommends logging in with just your username and no password. Were this that easy we could just move on to the next step. I reset my user id in users.xml to "Admin", blanked out the password, and gave it a shot. What I got was this:

image

Clearly trying to login with a blank password isn't going to work.

Here's what I did to get around this:

a.) Open up the users.xml file in the default web site you downloaded earlier. You'll see the default Admin login along with this:

<Password>jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg=</Password>

Turns out this is the encrypted form of the word "admin".

b.) Copy the encrypted password into your own users.xml file. Save it.

c.) Login using your username (or "Admin" if you used the above screen shot as a guide) and a password of "admin".

d.) Edit individual id's and, of course, change the admin password or delete the id altogether.

Not sure how Al was able to login with a blank password. In any case, the above procedure worked for me.

10.) Deploy the new site

Once you're satisfied everything is in place, FTP to your site and deploy the new site. Al recommends wiping the slate clean: delete everything to start so as not to leave any orphaned files out there. If you created your new 1.4.5 site as I described above you can then ftp its entire contents as is. If you did not copy your most current App_Data folder into the new, local site, then don't copy your App_Data folder. You'll overwrite your existing data. Also, if you just want to be ultra-safe, just copy everything but the App_Data folder. Up to you.

Personally, I'd rather have a few orphaned files out there than take the chance of missing something crucial. I did an overlay of the new site onto the old.

 

Conclusion

If all went well, you should be done. Go to your site and verify it works as expected.

 

Some Addendums

All did not go as smoothly as I would have liked. While I tried to exclude any snafu's that might have arisen solely because of my own proprietary changes or mistakes, I wanted to at least throw some of these things out so that if others run into the same problems, either someone can enlighten me as to the cause or we can at least try to figure it out together.

1.) XML Parsing Error on login/logout

I had a lot of issues with getting my id/password back to the defaults so I could then enter a new password and have it encrypted. One such problem was this "XML Parsing Error":

image

I got this a number of times both when trying to login and logout. Ultimately, I had to copy over the default users.xml and roles.xml. Even that didn't do it until I restarted the ASP.NET development server and switched browsers. I can't tell you exactly what made the above screenshot go away… if anyone knows and wants to share, post a comment.