Как стать автором
Обновить

MetaWeblog API в.NET

Время на прочтение4 мин
Количество просмотров2.1K
MetaWeblog, скажу я вам, — довольно занятная вещица. Простая и ясная аки двери. Когда всё там поймешь.

О протоколах


Впервые я столкнулся с этим интерфейсом в тот момент, когда прикручивал к своему вики-движку API для редактирования этих самых вики-страниц и постов в блоги. Blogger API не подошел из-за того, что ребята из Google, занятые разработкой GData API, основанного на Atom Publishing Protocol, от него отвернулись, а сам APP еще не был стандартизирован. По Movable Type API не нашлось внятной документации, а других как-то и не нашлось.

О русских программистах


Как бы то ни было, остановился я на MetaWeblog API. Поскольку построен он поверх XML-RPC, возникла потребность в библиотеке, которая брала бы все эти низкоуровневые детали на себя. Таковая нашлась: XML-RPC.NET (автор — Charles Cook). Неплохая, в общем-то, библиотека, но не без минусов. Во-первых, слишком тяжеловесная — там тебе и кодогенерация, и поддержка Remoting, и возможность создать свой stand-alone 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 и является) этого достаточно. Если же потребуется передавать структуры (слово «структура» я употребляю применительно к XML-RPC, а не к .NET), то класс (вот здесь речь уже о .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 стала делом до неприличия простым: унаследовать класс сервиса от 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)));
    }
  }
}
Теги:
Хабы:
0
Комментарии1

Публикации

Изменить настройки темы

Истории

Работа

.NET разработчик
72 вакансии

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн