Coding blog engine with MetaWeblog API support and using it with Windows Live Writer
In this article I’d like to describe MetaWeblog API and later share some c# examples of using it with Windows Live Writer. I started thinking about writing custom blog engine which will support MetaWeblog API after discovering that Windows Live Writer support this API.
What is Windows Live Writer?
A Microsoft programm which allow you to make posts to most favorites blog engines.
What is MetaWeblog API?
The MetaWeblog API (MWA) is a programming interface that allows external programs to get and set the text and attributes of weblog posts. It builds on the popular XML-RPC communication protocol.
What is XML-RPC?
It’s remote procedure calling using HTTP as the transport and XML as the encoding. XML-RPC is designed to be as simple as possible, while allowing complex data structures to be transmitted, processed and returned.
First I’d like briefly talk about XML-RPC and it’s C# implementation. On XML-RPC XML-RPC.NET package with tons of examples and docs. Using this package you can simply add xml-rpc support to your classes by adding several attributes (XMLRpcService, XmlRpcMethod). Below you can see example of blogger class with xml-rpc support
[XmlRpcService( Name = "blogger", Description = "This is a sample XML-RPC service illustrating method calls with simple parameters and return type.", AutoDocumentation = true)] [XmlRpcUrl("http://gtrifonov.azurewebsites.net/MetaBlogApi.ashx")] public class blogger : XmlRpcService { [XmlRpcMethod("metaWeblog.newPost")] public string newPost(string blogid, string username, string password, XmlRpcStruct rpcstruct, bool publish) { } }
As you noticed newPost method use parameter with type of XmlRpcStruct. This type represents XML-RPC struct data type . In XML-RPC there are few simple data types,array datatype and XML-RPC struct data type which is basically simple representation of dictionary.
MetaWeblog API interface
MetaWeblog API interface contains following methods:
- metaWeblog.newPost (blogid, username, password, struct, publish) returns string – Add new post
- metaWeblog.editPost (postid, username, password, struct, publish) returns true – Edit existing post
- metaWeblog.getPost (postid, username, password) returns struct – Returns existing post
- metaWeblog.getCategories (blogid, username, password) returns struct – Returns blog categories
- metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts) returns array of structs – Return recent posts
- metaWeblog.newMediaObject (blogid, username, password, struct) returns struct – Add new media object to post
When I started coding and testing this interface I found that Windows Live Writer called blogger.getUsersBlogs and blogger.deletePost methods which actually defined in Blogger API. I defined these methods with appropriate XmlRPcMethod attributes in my blogger class and start coding: Below you can find skeleton of my blogger class:
using System; using System.Web; using CookComputing.XmlRpc; using System.Xml; using System.Xml.Xsl; using System.Xml.XPath; using System.Collections.Generic; using System.IO; [XmlRpcService( Name = "blogger", Description = "This is a sample XML-RPC service illustrating method calls with simple parameters and return type.", AutoDocumentation = true)] [XmlRpcUrl("http://gtrifonov.azurewebsites.net/MetaBlogApi.ashx")] public class blogger : XmlRpcService { [XmlRpcMethod("blogger.getUsersBlogs")] public XmlRpcStruct[] getUsersBlogs(string appKey, string username, string password) { .... return struct; } [XmlRpcMethod("metaWeblog.setTemplate")] public bool setTemplate(string appKey, string blogid, string username, string password, string template, string templateType) { return true; } [XmlRpcMethod("metaWeblog.getCategories")] public XmlRpcStruct[] getCategories(string blogid, string username, string password) { XmlRpcStruct rpcstruct = new XmlRpcStruct(); rpcstruct.Add("description", "description"); rpcstruct.Add("categoryid", "123"); rpcstruct.Add("title", "title"); return new XmlRpcStruct[] { rpcstruct }; } [XmlRpcMethod("metaWeblog.getRecentPosts")] public XmlRpcStruct[] getRecentPosts(string blogid, string username, string password,int numberOfPosts) { XmlRpcStruct[] posts = new XmlRpcStruct[5]; ....... return posts; } [XmlRpcMethod("metaWeblog.getTemplate")] public string getTemplate(string appKey, string blogid, string username, string password, string templateType) { ..................... return id; } [XmlRpcMethod("metaWeblog.editPost")] public bool editPost(string postid, string username, string password, XmlRpcStruct rpcstruct, bool publish) { .................. return true; } [XmlRpcMethod("metaWeblog.getPost")] public XmlRpcStruct getPost(string postid, string username, string password) { .................. return rpcstruct; } [XmlRpcMethod("blogger.deletePost")] public bool deletePost(string appKey, string postid, string username, string password, bool publish) { return false; } [XmlRpcMethod("metaWeblog.newMediaObject")] public XmlRpcStruct newMediaObject(string blogid, string username, string password, XmlRpcStruct rpcstruct) { bool allowed = System.Web.Security.FormsAuthentication.Authenticate(username, password); return rstruct; } }
Issues:
After defining all methods and adding basic functionality I figure out that Windows Live Writer not using getTemplate and setTemplate method and trying to detect your blog appearance by connecting to blog site and downloading content. It’s strange because these methods were designed especially for this.
Also I found that in xml-rpc RFS documentation method getRecentPosts returns struct with array of posts, but Windows Live Writer expecting to receive array of structs.
If you tried coding method getCategories looking only to RFS it will not work with Windows Live Writer, because writer expecting categoryid as one of structure member. Thanks to Wiktor for his post with example of how to avoid this issue and example of working structure.
<?xml version="1.0"?> <methodResponse> <params> <param> <value> <array> <data> <value> <struct> <member> <name>categoryid</name> <value>1</value> </member> <member> <name>title</name> <value>Category 1</value> </member> <member> <name>description</name> <value>Description </value> </member> </struct> </value> </data> </array> </value> </param> </params> </methodResponse>
I hope issue with template methods and categories will be solved in next Windows Live Writer beta releases.
Download MetaWeblog API example (C#)
References: