プロトコルについて
APIをWikiエンジンにねじ込んで、これらの同じWikiページとブログ投稿を編集した瞬間、このインターフェイスに最初に出会いました。 Blogger APIは 、 Atom Publishing Protocolに基づいてGData APIを開発していたGoogleのスタッフが彼から遠ざかり、APP自体がまだ標準化されていなかったため、 適切ではありませんでした。 Movable Type APIのわかりやすいドキュメントはありませんでしたが、他にはありませんでした。
ロシアのプログラマーについて
ともあれ、MetaWeblog APIに決めました。 XML-RPCの上に構築されたため、これらの低レベルの詳細をすべて自分自身に取り込むライブラリが必要でした。 1つが見つかりました: XML-RPC.NET (著者-Charles Cook )。 一般的には優れたライブラリですが、欠点がないわけではありません。 まず、重量が大きすぎる-コード生成、Remotingサポート、独自のスタンドアロンXML-RPCサーバーを作成する機能などが得られます。 第三に、ドキュメントはそれほど熱くありません。 最後に、構造をシリアル化するときに、パブリックフィールドのみが考慮されます。これはそれほど悪くないかもしれませんが、私には向いていませんでした。
要するに、彼自身のライブラリを書くことが決定されました(そうそう、「 彼らはそれを書いていない 」も重要な要素です)。 結果はGoogle Codeで入手できます。
octalforty brushie web
そうです、そうです。
最も重要なクラスは
XmlRpcService
です。 有名な
System.Web.IHttpHandler
抽象化して実装します。 独自のXML-RPCサービスを作成するには、このクラスから継承し、公開されたメソッドを
XmlRpcServiceMethodAttribute
属性でマークするだけで十分です。
public class MathXmlRpcService : octalforty.Brushie.Web.XmlRpc.XmlRpcService
{
[XmlRpcServiceMethod("add")]
public int Add(int x, int y)
{
return x + y;
}
}
プリミティブ型(
int
)の場合、これで十分です。 構造を転送する必要がある場合(.NETではなくXML-RPCを参照して「構造」という言葉を使用します)、クラス(ここでは.NETについて説明しています)に追加のマークを付ける必要があります。
[XmlRpcStructure()]
public class BlogPostCategory
{
private string title = String.Empty;
[XmlRpcMember("title")]
public string Title
{
get { return title; }
set { title = value; }
}
}
それは基本的にそれです。 XML-RPCについて知る必要はありません。
MetaWeblog API
次に、API自体を実装する番です。
octalforty.Brushie.Web.XmlRpc.XmlRpcService
と関連するすべてのインフラストラクチャを手に入れたので、やや曖昧な仕様を理解し、適切なコードを記述することは、まだ少しの作業です。 Fiddlerを手に取り、 Windows Live Writerを手に取って、研究を始めました。 その結果、 そのような石の花が出てきました。
これで、APIの実装が
IMetaWeblogService
XmlRpcService
なりました
IMetaWeblogService
からサービスクラスを継承し、
XmlRpcService
を実装し
IMetaWeblogService
。
終わりに向かって...
...
NewMediaObject
の実装がどのように見えるかの例。
namespace octalforty.Kudos.Web.Api.Wiki
{
/// /// A MetaWeblog XML-RPC service for editing wiki pages.
///
public class MetaWeblogService : XmlRpcService, IMetaWeblogService, IPageManagerServiceDependency,
ISpaceManagerServiceDependency, INavigationServiceDependency,
IGlobalTagManagerServiceDependency, ISecurityServiceDependency,
IUserManagerServiceDependency, IPageAttachmentManagerServiceDependency
{
public MediaObjectInfo NewMediaObject(string blogID, string login, string password, MediaObject mediaObject)
{
if(!SecurityService.IsValid(login, password))
throw new SecurityException();
//
// Parsing media object name.
if(mediaObject.Name.IndexOf("^") < 0)
throw new ArgumentException();
string pageName = mediaObject.Name.Substring(0, mediaObject.Name.IndexOf("^"));
string attachmentName = mediaObject.Name.Substring(mediaObject.Name.IndexOf("^") + 1);
Space space = SpaceManagerService.GetSpaceByID(Convert.ToInt64(blogID));
Page page = PageManagerService.GetPageBySpaceKeyAndPageName(space.Key, pageName);
PageAttachment pageAttachment = PageAttachmentManagerService.GetPageAttachmentByName(page, attachmentName);
if(pageAttachment == null)
{
pageAttachment = new PageAttachment(attachmentName, mediaObject.MimeType);
page.AddAttachment(pageAttachment);
} // if
pageAttachment.AddRevision(new PageAttachmentRevision(UserManagerService.GetUserByLogin(login), mediaObject.Content));
PageManagerService.SavePage(page);
return new MediaObjectInfo(NavigationService.ResolveVirtualUrl(NavigationService.GetPageAttachmentUrl(pageAttachment)));
}
}
}