Getting Started with My.Blogs
Updated November 2005
Microsoft Visual Basic 2005
Summary: My.Blogs is a collection of sample code that will show you how you can easily provide programmatic access to weblogs in the applications you build. Full source code is provided along with Windows Forms, ASP.NET 2.0, and a Visual Studio 2005 Tools for Office Outlook Add-In. (15 printed pages)
Download the associated code sample, MyBlogs.msi, for this article.
Weblogs and weblog feeds (XML representations of blogs entries) have changed the way we share information. Whether you're looking for information about Microsoft Visual Basic, software development in general, or even your favorite hobby, chances are there are a number of blogs covering the subject if you're not already blogging it yourself.
Moving forward, it makes sense that we as Visual Basic developers will want to add this type of communication and community support to our own Microsoft Windows Forms, Microsoft ASP.NET, Microsoft Office 2003, and mobile applications. The .NET Framework 2.0 makes writing code based on networking (like HTTP) and XML schemas (like RSS 2.0) incredibly straightforward. Visual Basic 2005 makes creating and accessing this code in other projects incredibly easy by leveraging the My namespace.
My.Blogs is a collection of sample code that will show you how you can easily provide programmatic access to weblogs in the applications you build. The My.Blogs sample code supports reading from blogs feeds (including RSS 2.0, ATOM 1.0, and RDF 1.0) as well as posting entries to blog servers (using the MetaWebLog API). This sample is based the Beta 2 version of Visual Studio 2005, Visual Basic 2005, and the .NET Framework 2.0. The code is supplied "as-is" and is intended as sample code that you can use for educational purposes and extend for use in your applications.
To get started using My.Blogs, download the sample code to your local machine and extract the files associated with the sample to a directory on your local machine. Follow these steps to start using My.Blogs to work with weblog feeds programmatically.
- Start by opening the "\My.Blogs VS Snippet and Add In" from the code you extracted above.
- Double-click on My.Blogs.vsi and accept all the default options. This will install a new Template to the Add New Item dialog box called "My.Blogs".
- Open Visual Studio 2005 and select File|New Project. Select Visual Basic 2005 as your language, Windows for the Project Type, and Windows Application as the Template.
- Name your project "UsingMyBlogs."
- In the Solution Explorer, right click on the UsingMyBlog project and select Add|New Item...
- In the Templates List, scroll down until you get to My Templates and select My.Blogs. Click Add.
- In Solution Explorer, notice that a file called MyBlogs.vb has been added to your project.
- In Solution Explorer, double-click on the My Project folder and select the References tab. Note that you now have a reference to the MyBlogs.dll. This was done for you by adding the My.Blogs template to your project.
- If your reference was not made correctly, you'll need to set it up manually. Save the project and copy the MyBlogs.dll to the debug/bin folder and add a reference to MyBlogs.dll using the My Projects folder.
- Double-click on Form1.vb in the Solution Explorer to open it in the form designer.
- Drag a DataGridView onto Form1 and set the following properties:
- Name = "BlogEntries"
- AllowUserAddRows = False
- AllowUserDeleteRows = False
- ReadOnly = True
- SelectionMode = FullRowSelect
- Drag a button on the form under the BlogEntries DataViewGrid.
- Double-click the button to start writing code behind the ClickEvent.
- Type in the following code in the Button1_Click event handler:
Dim MyFeed As MyBlogs.Feed MyFeed = My.Blogs.Read("http://blogs.msdn.com/vbteam/Rss.aspx") Me.BlogEntries.DataSource = MyFeed.Entries
- That's all the code you need to read from a blog feed and populate the entries into a grid. The Read method returns a Feed object that represents the entries for a given RSS/ATOM/RDF feed at a given URL. The Feed.Entries property returns a BindingList(Of FeedEntry), which allows you to bind the list directly controls like the DataGridView.
- Run the application. It should look like the following:
Figure 1. A simple Windows Forms Application using My.Blogs
- If you look at the Title column and compare it to the blog entries at http://blogs.msdn.com/vbteam/rss.aspx, you'll note that you have now loaded a live RSS feed into your sample application with three lines of code!
- Close the application and add another button to the form. Double-click that button and add the following code to Button2_Click:
myFeed = My.Blogs.Read("http://blogs.msdn.com/vbteam/Rss.aspx", False, _ New Date(2005, 7, 1)) Me.EntriesGridView.DataSource = myFeed.Entries
- You can see that this overload of the Read method takes two arguments. The first is a Boolean for whether you want to download comments for each feed. The second is a date. This allows you to only retrieve entries on or after a certain date. This is useful if you are creating an application that only reads feed entries since the last time you performed a Read. Run the application and click on Button2. Your application should look like this:
Figure 2. A Simple Windows Forms Application Reading Feeds from A Date
- Only entries dated on or after 7/1/2005 were returned. Close the applications.
- Drop another button onto the form and add the following code to the Button3_Click event handler.
Private MyFeed As MyBlogs.Feed Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click MyFeed = My.Blogs.Read("http://blogs.msdn.com/vbteam/Rss.aspx", True) Me.BlogEntries.DataSource = MyFeed.Entries End Sub
- Note the promotion of MyFeeds to a module lever variable. Also note that we're using yet another overload of My.Blogs.Read that accepts the feed URL as well as a Boolean for retrieving feed comments. We've set it to True in order to retrieve comments.
- Add another DataGridView to Form1 and place it under the buttons. Set the following properties:
- Name = "BlogEntryComments"
- AllowUserAddRows = False
- AllowUserDeleteRows = False
- ReadOnly = True
- SelectionMode = FullRowSelect
- Right-click on Form1 and select View Code. Add a new event handler for the BlogEntries control by selecting Blog_Entries in the Class drop down and SelectionChanged in the method drop down. You should have a new event handler called BlogEntries_SelectionChanged. Add the following code:
Dim SelectedEntry As MyBlogs.FeedEntry = MyFeed.Entries(BlogEntries.CurrentRow.Index) If SelectedEntry.Comments IsNot Nothing Then Me.BlogEntryComments.DataSource = SelectedEntry.Comments.Entries End If
- Run the application. It should look like the figure below.
Figure 3: Reading Feeds and Their Comments
- When you select an entry in the entry grid that has comments associated with it, the comments show up in the BlogEntryComments grid. Your application is now reading blog entries and their comments from a RSS feed. Close the application.
- MyBlog supports posting to blogs as well. In order to post to a blog you'll need the following information:
- The blog URL.
- The ID you use to sign in to that blog.
- The password you use to sign in to that blog.
- Add another button to the form and double-click on the button to create the Button4_Click event handler. Add the following code:
My.Blogs.PublishEntry(_ MyBlogs.PublishFormat.CommunityServerViaMetaWebLogAPI, _ "http://myblogserver/myblogid", "myblogid", "password", _ "Testing via UsingMyBlogs", "This is the entry posted " + _ "from trying out MyBlogs!") MyFeed = My.Blogs.Read("http://myblogserver/myblogid/rss.aspx", True) Me.BlogEntries.DataSource = MyFeed.Entries
- Run the application and click on Button4. When the BlogEntries DataGridView is populated, you'll see the blog entry you posted using My.Blogs. It may take a few minutes for the new post to show up. The first argument you pass to PublishEntry is a value from the PublishFormat Enum, telling My.Blogs what publish format you're going to use to post the entry. More on that later. Close the application.
- MyBlogs supports reading and writing OPML lists of blog feeds. OPML is an XML schema for managing outlines, such as groups of blog feed addresses. A sample OPML file, appropriately named sample.opml, is supplied in the root of the sample code. Copy it to the \bin\debug directory of UsingBlogs.
- Next, drop another button onto Form1 and add an event handler by double-clicking on the button.
- Add the following code to the Button5_Click event handler.
Dim SampleBlogs As Generic.List(Of MyBlogs.BlogGroup) = My.Blogs.ReadOpml( _ My.Computer.FileSystem.CurrentDirectory + "\" + "sample.opml") Dim SampleBlogInfo As MyBlogs.BlogInfo = SampleBlogs(0).Item(0) myFeed = My.Blogs.Read(SampleBlogInfo.FeedUrl) Me.EntriesGridView.DataSource = myFeed.Entries
- This code deserves some explanation. OPML files allow you to group information about blog feeds into groups. My.Blogs reflects that grouping by returning a List(Of MyBlogs.BlogGroup) that you can use to get individual instances of the MyBlogs.BlogInfo class, which provide information about an individual feed (such as its URL). The code above reads the OPML file, uses the first BlogInfo to get a feed URL and then loads the feed into the EntriesGridView.
- Run the application. You will see the feed entries for the first entry of the OPML file in the DataGridView. Close the application.
- Finally, My Blogs allows you to write OPML files as well. Drop another button onto Form1 and double-click on the form to add an event handler. Add the following code to Button6_Click.
Dim SampleBlogs As New Generic.List(Of MyBlogs.BlogGroup) Dim MyBlogGroup As New MyBlogs.BlogGroup Dim MyBlogInfo As New MyBlogs.BlogInfo() MyBlogInfo.FeedUrl = "http://blogs.msdn.com/vbteam/Rss.aspx" MyBlogInfo.Title = "VB Team Blog" MyBlogInfo.Url = "http://blogs.msdn.com/vbteam" MyBlogGroup.Add(MyBlogInfo) SampleBlogs.Add(MyBlogGroup) My.Blogs.WriteOpml(SampleBlogs, My.Computer.FileSystem.CurrentDirectory + "\" + "WriteSample.opml")
- Just like the last example, we use a MyBlogs.BlogInfo class to store the info about a feed. We then add that BlogInfo to a BlogGroup and use the My.Blogs.WriteOpml method to write the OPML file to disk. Open the OPML file from the \bin\debug directory to get an idea of what OPML looks like.
Congratulations! In only a few minutes, and with only a few lines of code, you've used My.Blogs to write code to perform common blog feed operations in code.
Before we take a look at how My.Blogs works under the hood, let's take a look at what an application based on My.Blogs and see what it can do. Follow these steps to get started using an application based on My.Blogs.
- Under the directory where the sample code was unzipped, open \My.Blogs Windows Sample\MyReader.sln.
- Run the application.
- MyReader is based on a communication application starter kit included with this sample, \Misc. Sample Files\Communication Application.vsi, which allows you to quickly create applications with an Office Outlook 2003 look and feel.
- Start using MyReader by subscribing to some blog feeds. You can do this through an OPML file or by entering a URL for an RSS, ATOM, or RDF feed.
- OPML—You can load feeds from another reader by exporting an OPML file of feeds and importing it into MyReader. For example, select File/Import Subscriptions and select the path of the sample.opml file supplied in the root of the sample code directory.
- By URL—Select File/New Feed and enter the URL of a valid RSS, ATOM, or RDF feed (such as http://blogs.msdn.com/vbteam/rss.aspx).
- At this point, you should see your feed(s) in the Feeds list box. Select a feed by clicking on it in the Feeds list on the left side of the UI and then select an entry in the right side of the UI. You will see the contents of the entry in the bottom half of the entry pane.
- You can also group your feeds to make easier to manage. Select File/New/Group... and give the group a name. To add a feed to the group, select the group and add the feed as you did above.
Posting to Blogs
- To post entries to your blog, you need to provide some key information to be used by the My.Blogs code running in MyReader. Select the Blog Info... toolbar button to supply the necessary information. Enter the following information based on your blog:
- User ID—This is the user ID that you use to log into your blog server.
- Password—The password you use to log into your blog server.
- Publish Protocol—How you'd like to post to your blog server.
- Community Server using a Blog URL: If you are using Community Server (http://www.telligent.com/), you can just enter your blog URL (for example http://blogs.msdn.com/vbteam) and My.Blogs will calculate the service endpoint for you. Select this option in order to post using that method.
- Metablog API through a Service URL—If you are using a server other than Community Server that supports the MetaBlog API, enter the Metablog API service URL here. For example, http://blogs.msdn.com/metablogapi.aspx. Select this option in order to post by means of this method.
- Blog URL/Service URL—The URL that corresponds to the selection you made above.
- Blog ID—For the Metablog API selection, you need to supply the blog ID. Most often, it's the directory name of your blog. For example, if your blog is http://blogs.msdn.com/vbteam, your Blog ID would be vbteam.
- After providing information about your blog, you're ready to post an entry. Click the Write to Blog button. The reading pane changes into a blog entry pane. Enter the title of the entry and the content of the entry and click the Publish button. If you entered your blog information correctly, you will be able to go to the blog (or the feed if you've added it to MyReader) and see the post.
There are some other great samples included with MyBlogs. Take a deeper look at the MyReader.sln in order to see how to consume blog feed functionality in a Windows Forms application. In the "My.Blogs Web Sample" folder you'll see a sample Web site that uses My.Blogs to provide blog reading functionality to an ASP.NET 2.0 application. In the "My.Blogs Office Outlook Add-In" folder there is an example of using My.Blogs in order to provide blog functionality within Outlook 2003 using Microsoft Visual Studio 2005 Tools for the Microsoft Office System. One thing that you'll notice is that the design of My.Blogs allows each application, regardless of whether the application is a Windows Forms application, Web application, or Outlook Add-In, to provide blog feed access with some simple calls to My.Blogs.
In order to understand how My.Blogs works, you really need to look at three things; how My.Blogs extends the My feature, how the Blogs class provides the implementation of My.Blogs, and how publishing and reading are accomplished.
Adding Blogs to the My Feature.
If you're new to Visual Basic 2005, you're probably new to the My feature. My provides quick access to common development tasks and common information through an easy-to-use object hierarchy. The great thing about My is that you can extend it using classes of your own design.
To access the Blogs class (which provides the actual implementation) through the My feature, you need to add a key piece of code to the consuming application. In the previous sample, that key piece of code was provided in the MyBlogs.vb file when we added the MyBlogs template to the project.
Namespace My <Global.Microsoft.VisualBasic.HideModuleName()> _ Module MyBlogs Private _blogs As New ThreadSafeObjectProvider(Of Global.MyBlogs.Blogs) Public ReadOnly Property Blogs() As Global.MyBlogs.Blogs Get Return _blogs.GetInstance() End Get End Property End Module End Namespace
This code is pretty straightforward. Extending My is mainly a matter of adding a property to the My namespace. That property returns an instance of the Blogs class wrapped in a ThreadSafeObjectProvider, which provides a thread safe instance of Blogs to each request. See the article "Simplify Common Tasks by Customizing the My Namespace" for more details (a link to the article is provided).
The Blogs Class
Let's take a look at the Blogs class to see the actual implementation of the blog posting and feed reading functionality provided in My.Blogs. Open the "My.Blogs.sln" solution in the "My.Blogs DLL Source Code" folder. Take a look at the class diagram ClassDiagram1.cd and look at the Blogs class.
Figure 4. The Blogs Class Diagram
As you'd expect, the implementation mimics what is provided by My.Blogs. If you look at the methods themselves in code, you'll notice one thing of interest. The Blogs class uses a Factory-like pattern in order to provide the function of reading feeds using varied feed formats.
Let's take a look at the Read method. We'll examine the simplest form of the Read method, since all the other overloads follow the same pattern. Open the MyBlogs.vb file in the solution to see the Blogs class. The implementation of Read is here:
Public Function Read(ByVal Url As String) As Feed Return MyBlogs.Feed.Read(Url, False) End Function
If you follow this to the Feed class in Feed.vb, you'll note that the Feed class gets the feed XML from the URL passed to Blogs.Read() and returns an instance of a class that represents the specific feed format.
Public Shared Function Read(ByVal url As String, _ ByVal loadComments As Boolean, ByVal subscriptionDate As Date) As Feed Dim format As FeedFormat Dim feed As Feed = Nothing Dim xml As XmlReader = Nothing Dim client As New System.Net.WebClient() Dim stream As IO.Stream = Nothing Try stream = client.OpenRead(url) xml = XmlReader.Create(stream) format = GetFeedFormat(xml) Select Case format Case FeedFormat.Atom feed = New Atom.AtomFeed feed.Load(xml) Case FeedFormat.RDF feed = New Rdf.RdfFeed() feed.Load(xml) Case FeedFormat.RSS feed = New Rss.RssFeed() feed.Load(xml, subscriptionDate) End Select Catch e As Exception Throw e Finally If xml IsNot Nothing Then xml.Close() End If If stream IsNot Nothing Then stream.Close() End If End Try If feed IsNot Nothing Then feed.ShouldDownloadComments = loadComments feed.LoadComments() feed.FeedUrl = url End If Return feed End Function
You can see the relationship between Feed and the different subclasses of Feed that provide specific feed implementations in the following diagram.
Figure 5. Feeds and FeedEntry Diagram
FeedEntry provides the implementation of individual entries in a feed and works the same way.
Extending Read to support more formats is just a matter of adding a value to the FeedFormat Enum, providing a new subclass of Feed and FeedEntry, as well as providing the specific implementation of that format.
Publish works in the same way. Here is the code from the Blogs class that provides the basic Publish implementation. When calling PublishEntry, you need to pass a value from the PublishEntry Enum so the right publish implementation class is created.
Public Sub PublishEntry(ByVal Format As PublishFormat, _ ByVal BlogURL As String, ByVal UserName As String, _ ByVal Password As String, ByVal Title As String, _ ByVal Description As String) PublishProvider.PublishEntry(Format, BlogURL, UserName, _ Password, Title, Description, True) End Sub
Again, the PublishProvider class provides the actual implementation by using the PublishFormat Enum to dictate what class is actually created to do the actual publishing.
Public Shared Sub PublishEntry(ByVal format As PublishFormat, ByVal Address As String, ByVal UserName As String, ByVal Password As String, ByVal Title As String, ByVal Description As String, ByVal IsNewEntry As Boolean) Dim provider As PublishProvider = PublishProvider.Create(format) provider.PublishEntry(Address, UserName, Password, Title, Description) End Sub Friend Shared Function Create(ByVal format As PublishFormat) As PublishProvider 'Create http request and send it to server Dim provider As PublishProvider = Nothing Select Case format Case PublishFormat.Unknown Throw New System.Exception("PublishFormat.Unknown") Case PublishFormat.MetaWebLogAPI provider = New MetaWebLogPublishProvider() Case PublishFormat.CommunityServerViaMetaWebLogAPI provider = New MetaWebLogPublishProvider() Case Else Throw New System.Exception() End Select Return provider End Function
If you look at ClassDiagram1.cd again, you'll see that PublishProvider follows the same pattern as the Feed class.
Figure 6. Publish Provider Diagram
Currently, only the MetaWeblog API is supported for Telligent's Community Server using the MetaWebLogPublishProvider subclass, but you could easily extend the PublishProvider to support other APIs or other servers by providing a new subclass with a new implementation.
The My.Blogs sample is great from a couple of points of view. First, it provides a great example of how you can extend My to provide a very clean and intuitive way of accessing common functionality throughout your code. Second, it's a great sample application that you can easily extend in order to build a full featured blog utility, whether you want to work with blogs on your desktop, from a browser or even inside Outlook. Enjoy!