I'm Keyvan Nayyeri, a 25 years old Ph.D. student at
the Computer Science department of
the University of Texas at San Antonio.
I'm also
a Software Architect and Developer and previously held a B.Sc.
degree in Applied Mathematics.
This is my blog where I publish content about various topics specifically Programming Languages and Compilers, Software
Engineering and Programming.
There is no doubt that MetaWeblog API is one of the very helpful and popular inventions around online publishing especially for blog engines and services. Of course MetaWeblog API has not been a tool only for blogs because it's used as a general publishing service for other sites as well.
During the time, MetaWeblog API is extended by some famous blogging engines and services like Blogger and WordPress to add some common features to it but the core features are what many users are looking for.
There are several plus points for MetaWeblog API that has made it a great choice for online publishing including the ease of editing, capability of having a local copy and many other features. Some great tools like Windows Live Writer or BlogJet are working based on these APIs.
MetaWeblog API is simply built on top of XML-RPC API which acts based on XML communications between a client and a server. This API consists of some structures for common objects in blogging (like blog, user, post, category or media objects) as well as some methods to add, edit, get or delete them.
There are many implementations for MetaWeblog API in different technologies including .NET (ASP.NET) but I couldn't find any good resource that helps much for .NET implementation. The first time that I was going to implement this API for a site, after some researches I finally ended up with discovering an open source implementation code.
So I'm going to write this post to describe how to implement MetaWeblog API in .NET in the simplest form that I can.
As I stated above, MetaWeblog API is an API based on XML-RPC communications. It means that you have a set of pre-defined structures (with simple data types as properties) that are being transferred between client and server. There are also some methods that apply these structures.
There are six structures that you need to use in the MetaWeblog API:
As a general rule, you can keep in mind that MetaWeblog API uses string type as the basic type for many properties, parameters and return types and there isn't any integer type. Boolean and base64 encoded string are two other types in a few places.
There are also nine methods to use in the MetaWeblog API:
These structures and methods have a pre-defined structures with special data types and you must keep their structures in your code because they're a standard structure and all the tools and clients are built to work with them.
This is the main part of MetaWeblog API (not its core and original implementation) but I wrote that some famous blogging engines and services like Blogger or WordPress have added a few features to this core functionality with new structures that have become common among users. For example, Blogger has three helpful methods including blogger.deletePost, blogger.getUserInfo and blogger.getUsersBlogs.
Here I ignore WordPress addition but cover Blogger methods because they're very common. The usage and implementation of other methods is very similar to the core features.
The process of implementing MetaWeblog API for your .NET applications is straightforward and consists of a few steps that I'll describe. But before talking about these steps, there is an obvious requirement for the implementation and that is a library to work with XML-RPC in .NET. You most likely know the most common and famous one, XML-RPC.NET, that is serving in many .NET applications. You just need to add a reference to this assembly in your projects.
But how about the implementation? The implementation consists of four steps in general:
I describe each step in the next sections.
The first and simplest step is to create a webservice or HTTP Handler to act as the entry point for the API. Below code is enough to do this for me and move the rest to my MetaWeblog class implementation.
<%@ WebHandler Language="C#" CodeBehind="MetaWeblogAPI.ashx.cs" Class="MetaWeblogSample.MetaWeblogAPI" %>
Now you need to build the abovementioned structures of MetaWeblog API in your code. I don't step in details about the structures since they're constant structures that you can understand from MetaWeblog API specification.
The below code is all I need to build my structures. You usually can simply use same code in your applications because these are constant structures.
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using CookComputing.XmlRpc;
namespace MetaWeblogSample
{
#region Structs
public struct BlogInfo
{
public string blogid;
public string url;
public string blogName;
}
public struct Category
{
public string categoryId;
public string categoryName;
}
[Serializable]
public struct CategoryInfo
{
public string description;
public string htmlUrl;
public string rssUrl;
public string title;
public string categoryid;
}
[XmlRpcMissingMapping(MappingAction.Ignore)]
public struct Enclosure
{
public int length;
public string type;
public string url;
}
[XmlRpcMissingMapping(MappingAction.Ignore)]
public struct Post
{
public DateTime dateCreated;
public string description;
public string title;
public string[] categories;
public string permalink;
public object postid;
public string userid;
public string wp_slug;
}
[XmlRpcMissingMapping(MappingAction.Ignore)]
public struct Source
{
public string name;
public string url;
}
public struct UserInfo
{
public string userid;
public string firstname;
public string lastname;
public string nickname;
public string email;
public string url;
}
[XmlRpcMissingMapping(MappingAction.Ignore)]
public struct MediaObject
{
public string name;
public string type;
public byte[] bits;
}
[Serializable]
public struct MediaObjectInfo
{
public string url;
}
#endregion
}
The next step is to build an interface for MetaWeblog API based on the structures that you have defined. You need to mark your methods with an XmlRpcMethod attribute (included in XML-RPC.NET library) that gets the service method name as its parameter. Again, this interface is obvious from the MetaWeblog specification. There are two groups of methods for core MetaWeblog API and Blogger API.
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using CookComputing.XmlRpc;
namespace MetaWeblogSample
{
public interface IMetaWeblog
{
#region MetaWeblog API
[XmlRpcMethod("metaWeblog.newPost")]
string AddPost(string blogid, string username, string password, Post post, bool publish);
[XmlRpcMethod("metaWeblog.editPost")]
bool UpdatePost(string postid, string username, string password, Post post, bool publish);
[XmlRpcMethod("metaWeblog.getPost")]
Post GetPost(string postid, string username, string password);
[XmlRpcMethod("metaWeblog.getCategories")]
CategoryInfo[] GetCategories(string blogid, string username, string password);
[XmlRpcMethod("metaWeblog.getRecentPosts")]
Post[] GetRecentPosts(string blogid, string username, string password, int numberOfPosts);
[XmlRpcMethod("metaWeblog.newMediaObject")]
MediaObjectInfo NewMediaObject(string blogid, string username, string password,
MediaObject mediaObject);
#endregion
#region Blogger API
[XmlRpcMethod("blogger.deletePost")]
[return: XmlRpcReturnValue(Description = "Returns true.")]
bool DeletePost(string key, string postid, string username, string password, bool publish);
[XmlRpcMethod("blogger.getUsersBlogs")]
BlogInfo[] GetUsersBlogs(string key, string username, string password);
[XmlRpcMethod("blogger.getUserInfo")]
UserInfo GetUserInfo(string key, string username, string password);
#endregion
}
}
And the last step is to implement your MetaWeblog API interface (IMetaWeblog in my example) as well as XmlRpcService from XML-RPC.NET library which simply turns your class to an XML-RPC service.
You need a logic to validate users based on their username and password and then let them do something in the methods. Here things vary based on your local implementation of blog engine or site so I just left code comments for the implementation part.
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using CookComputing.XmlRpc;
using System.Collections.Generic;
namespace MetaWeblogSample
{
public class MetaWeblog : XmlRpcService, IMetaWeblog
{
#region Public Constructors
public MetaWeblog()
{
}
#endregion
#region IMetaWeblog Members
string IMetaWeblog.AddPost(string blogid, string username, string password,
Post post, bool publish)
{
if (ValidateUser(username, password))
{
string id = string.Empty;
// TODO: Implement your own logic to add the post and set the id
return id;
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
bool IMetaWeblog.UpdatePost(string postid, string username, string password,
Post post, bool publish)
{
if (ValidateUser(username, password))
{
bool result = false;
// TODO: Implement your own logic to add the post and set the result
return result;
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
Post IMetaWeblog.GetPost(string postid, string username, string password)
{
if (ValidateUser(username, password))
{
Post post = new Post();
// TODO: Implement your own logic to update the post and set the post
return post;
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
CategoryInfo[] IMetaWeblog.GetCategories(string blogid, string username, string password)
{
if (ValidateUser(username, password))
{
List<CategoryInfo> categoryInfos = new List<CategoryInfo>();
// TODO: Implement your own logic to get category info and set the categoryInfos
return categoryInfos.ToArray();
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
Post[] IMetaWeblog.GetRecentPosts(string blogid, string username, string password,
int numberOfPosts)
{
if (ValidateUser(username, password))
{
List<Post> posts = new List<Post>();
// TODO: Implement your own logic to get posts and set the posts
return posts.ToArray();
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
MediaObjectInfo IMetaWeblog.NewMediaObject(string blogid, string username, string password,
MediaObject mediaObject)
{
if (ValidateUser(username, password))
{
MediaObjectInfo objectInfo = new MediaObjectInfo();
// TODO: Implement your own logic to add media object and set the objectInfo
return objectInfo;
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
bool IMetaWeblog.DeletePost(string key, string postid, string username, string password, bool publish)
{
if (ValidateUser(username, password))
{
bool result = false;
// TODO: Implement your own logic to delete the post and set the result
return result;
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
BlogInfo[] IMetaWeblog.GetUsersBlogs(string key, string username, string password)
{
if (ValidateUser(username, password))
{
List<BlogInfo> infoList = new List<BlogInfo>();
// TODO: Implement your own logic to get blog info objects and set the infoList
return infoList.ToArray();
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
UserInfo IMetaWeblog.GetUserInfo(string key, string username, string password)
{
if (ValidateUser(username, password))
{
UserInfo info = new UserInfo();
// TODO: Implement your own logic to get user info objects and set the info
return info;
}
throw new XmlRpcFaultException(0, "User is not valid!");
}
#endregion
#region Private Methods
private bool ValidateUser(string username, string password)
{
bool result = false;
// TODO: Implement the logic to validate the user
return result;
}
#endregion
}
}
At this point you're able to test the service simply by navigating to the URL of your HTTP Handler.

There are some extra implementations and features similar to this main implementation that you can inspire for your code. MetaWeblog API and its extended features are a great way to simplify the process of content publishing on your site and are easy to implement. I hope that more developers try to use it in their works. I can remember that three years ago I recommended this API to the founder and developer of the most famous and popular Persian blogging service but he never attended to my recommendation and it (along some other stuff) has kept his engine an amateur blogging engine (from a technical point of view).
You can download the source code sample of this post from here.
Implement MetaWeblog API in ASP.NET
May 10, 2008 8:22 AM
#
You've been kicked (a good thing) - Trackback from DotNetKicks.com
Dew Drop - May 10, 2008 | Alvin Ashcraft's Morning Dew
May 10, 2008 9:22 AM
#
Pingback from Dew Drop - May 10, 2008 | Alvin Ashcraft's Morning Dew
µilad
May 10, 2008 3:17 PM
#
Thanks for the gr8 and helpful post keyvan! For a long time I wanted to implement this, but I couldn't make it because of time problems!
BTW thanks again ;)
Reflective Perspective - Chris Alcock » The Morning Brew #91
May 12, 2008 2:22 AM
#
Pingback from Reflective Perspective - Chris Alcock » The Morning Brew #91
Wöchentliche Rundablage: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery… | Code-Inside Blog
May 14, 2008 6:50 AM
#
Pingback from Wöchentliche Rundablage: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery… | Code-Inside Blog
Weekly Links: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery… | Code-Inside Blog International
May 14, 2008 6:52 AM
#
Pingback from Weekly Links: ASP.NET MVC, Silverlight 2, TDD, WPF, jQuery… | Code-Inside Blog International
A cool article that shows how to implement MetaWebLog API in .NET « Scott Tucker’s Weblog
Jun 21, 2008 2:00 AM
#
Pingback from A cool article that shows how to implement MetaWebLog API in .NET « Scott Tucker’s Weblog
How to Implement Trackback Handler in ASP.NET
Jul 30, 2008 2:07 PM
#
Back in May I wrote a blog post as a guide to implement MetaWeblog API in ASP.NET . There are some common
How to Implement Pingback Handler in ASP.NET
Jul 31, 2008 3:20 PM
#
One of my yesterday’s blog posts was about implementing a trackback handler in ASP.NET and I stated that
MetaWeblog, Trackback and Pingback in ASP.NET « vincenthome’s Software Development
Aug 14, 2008 11:12 PM
#
Pingback from MetaWeblog, Trackback and Pingback in ASP.NET « vincenthome’s Software Development
Barry H.
Oct 24, 2008 7:02 AM
#
Great article! Thanks for sharing.
Sprogz
Nov 12, 2008 10:25 AM
#
Really helpful. Thank you.
Christian Groß
Nov 22, 2008 3:05 PM
#
Great work!
Monthly Top 10 Favorite useful Articles
Nov 29, 2008 7:55 AM
#
Monthly Top 10 Favorite useful Articles
Silverlight Travel
Dec 13, 2008 1:02 PM
#
Great idea. I us it now by myselfe.
My Best Blog Posts in 2008
Dec 31, 2008 1:40 PM
#
In the past 3.5 years of blogging, I haven’t had such best pick up collections in the end of the year, but now that everybody is writing one, why shouldn’t I write my own?! Collecting this list, I could realize some interesting facts that completely changed
Hans
Oct 22, 2009 5:53 AM
#
The zip file download for the source code is no longer available. Can I download this from somewhere else?
Keyvan Nayyeri
Oct 22, 2009 6:32 AM
#
You should be able to download it from the new link inserted in the post body.
shailesh
Nov 20, 2009 5:24 AM
#
hi Hans,
Really very nice blog.
Would you please now tell me how i can use this Api with my asp.net web page.
I mean from ms word 2007 which url and userid,pwd i should give and how i will get all that word contect in my .aspx page through this api..
Please help me....
Thanks in advance
Shailesh
Nov 20, 2009 5:27 AM
#
Sorry ....
Thanks to Keyvan Nayyeri
To post such a nice blog.....
shailesh
Nov 25, 2009 1:15 AM
#
Hi,
i did implement that code but as you did not give the complete integration with the webpage.
so when i merged this with asp.net site and registerd this tag add verb="*" path="channels.aspx" type="MetaWeblogSample.MetaWeblog, MetaWeblogSample in web.config file under the http tag.
But I did not get when any one click on publish button from msword-2007 then initialyy which method will call from Metaweblog API and how we can handle that event from .net
also i need the same formatiing which i have done in ms word , the same document formatting i need in in .net code and after that i will save it's content in db
so how i can implement all this methods in .net
kindly help me i have done many r&d on this but except your blog i could not find anything on this.so please help me to solve out this issue.
Many Many thanks in Advance...
praneeth
Jan 30, 2010 9:57 AM
#
Leave a Comment