XML-RPC简单理解与博客园的MetaWeblog协议

参考资料:

https://zh.wikipedia.org/wiki/XML-RPC
http://www.cnblogs.com/services/metablogapi.aspx


主要程序接口(来自博客园):

blogger.deletePost —— 删除文章

blogger.getUsersBlogs —— 获取用户博客信息

metaWeblog.editPost —— 编辑文章

metaWeblog.getCategories —— 获取用户博客分类

metaWeblog.getPost —— 获取文章

metaWeblog.getRecentPosts —— 获取最近的文章

metaWeblog.newMediaObject —— 添加媒体对象(图片等)

metaWeblog.newPost —— 添加文章

wp.newCategory —— 添加目录

接口说明


blogger.deletePost

请求

<?xml version="1.0"?>
<methodCall>
  <methodName>blogger.deletePost</methodName>
  <params>
    <param>
        <value><string>appkey</string></value>
    </param>
    <param>
        <value><string>postid</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
    <param>
        <value><boolean>0</boolean></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <boolean>1</boolean>
            </value>
        </param>
    </params>
</methodResponse>

blogger.getUsersBlogs

请求

<?xml version="1.0"?>
<methodCall>
  <methodName>blogger.getUsersBlogs</methodName>
  <params>
    <param>
        <value><string>appkey</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <array>
                    <data>
                        <value>
                            <struct>
                                <member>
                                    <name>blogid</name>
                                    <value>
                                        <string>dsafds</string>
                                    </value>
                                </member>
                                <member>
                                    <name>url</name>
                                    <value>
                                        <string>http://www.cnblogs.com/caipeiyu/</string>
                                    </value>
                                </member>
                                <member>
                                    <name>blogName</name>
                                    <value>
                                        <string>蛀牙</string>
                                    </value>
                                </member>
                            </struct>
                        </value>
                    </data>
                </array>
            </value>
        </param>
    </params>
</methodResponse>

metaWeblog.editPost

请求

返回


metaWeblog.getCategories

请求

返回


metaWeblog.getPost
请求

<?xml version="1.0"?>
    <methodCall>
      <methodName>blogger.getUsersBlogs</methodName>
      <params>
        <param>
            <value><string>postid</string></value>
        </param>
        <param>
            <value><string>username</string></value>
        </param>
        <param>
            <value><string>password</string></value>
        </param>
      </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <struct>
                    <member>
                        <name>dateCreated</name>
                        <value>
                            <dateTime.iso8601>时间</dateTime.iso8601>
                        </value>
                    </member>
                    <member>
                        <name>description</name>
                        <value>
                            <string>博客内容</string>
                        </value>
                    </member>
                    <member>
                        <name>title</name>
                        <value>
                            <string>标题内容</string>
                        </value>
                    </member>
                    <member>
                        <name>categories</name>
                        <value>
                            <array>
                                <data>
                                    <value>
                                        <string>[Markdown]</string>
                                    </value>
                                </data>
                            </array>
                        </value>
                    </member>
                    <member>
                        <name>enclosure</name>
                        <value>
                            <struct>
                                <member>
                                    <name>length</name>
                                    <value>
                                        <i4>0</i4>
                                    </value>
                                </member>
                            </struct>         
                        </value>
                    </member>
                    <member>
                        <name>link</name>
                        <value>
                            <string>http://.html</string>
                        </value>
                    </member>
                    <member>
                        <name>permalink</name>
                        <value>
                            <string>http://.html</string>
                        </value>
                    </member>
                    <member>
                        <name>postid</name>
                        <value>
                            <i4>00000</i4>
                        </value>
                    </member>
                    <member>
                        <name>source</name>
                        <value>
                            <struct />
                        </value>
                    </member>
                    <member>
                        <name>mt_keywords</name>
                        <value>
                            <string />
                        </value>
                    </member>
                </struct> 
            </value>
        </param>
    </params>
</methodResponse>

metaWeblog.getRecentPosts

请求

<?xml version="1.0"?>
<methodCall>
  <methodName>metaWeblog.getRecentPosts</methodName>
  <params>
    <param>
        <value><string>000000</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
    
    <param>
        <value><i4>10</i4></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <array>
                    <data>
                        <value>
                            <struct>
                                <member>
                                    <name>dateCreated</name>
                                    <value>
                                        <dateTime.iso8601>20160405T18:32:00</dateTime.iso8601>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>description</name>
                                    <value>
                                        <string>博客测试内容</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>title</name>
                                    <value>
                                        <string>标题测试内容</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>enclosure</name>
                                    <value>
                                        <struct>
                                            <member>
                                                <name>length</name>
                                                <value>
                                                    <i4>0</i4>
                        
                                                </value>
                      
                                            </member>
                    
                                        </struct>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>link</name>
                                    <value>
                                        <string>http://www.cnblogs.com/caipeiyu/p/5356274.html</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>permalink</name>
                                    <value>
                                        <string>http://www.cnblogs.com/caipeiyu/p/5356274.html</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>postid</name>
                                    <value>
                                        <string>5356274</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>source</name>
                                    <value>
                                        <struct />
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>userid</name>
                                    <value>
                                        <string>-2</string>
                  
                                    </value>
                
                                </member>
              
                            </struct>
            
                        </value>

          
                    </data>
        
                </array>
      
            </value>
    
        </param>
  
    </params>

</methodResponse>   

metaWeblog.newMediaObject

请求

返回


metaWeblog.newPost

请求
这个请求内容标题和内容是必须的,其他可以选填

<?xml version="1.0"?>
<methodCall>
  <methodName>metaWeblog.newPost</methodName>
  <params>
    <param>
        <value><string>postid</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
    <param>
         <value>
                <struct>
                    <member>
                        <name>description</name>
                        <value>
                            <string>博客测试内容</string>
                        </value>
                    </member>
                    <member>
                        <name>title</name>
                        <value>
                            <string>标题测试内容</string>
                        </value>
                    </member>
                    <member>
                        <name>categories</name>
                        <value>
                            <array>
                                <data>
                                    <value>
                                        <string>[Markdown]</string>
                                    </value>
                                </data>
                            </array>
                        </value>
                    </member>
                </struct> 
            </value>
    </param>
    <param>
        <value><boolean>0</boolean></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <string>000000</string>
            </value>
        </param>
    </params>
</methodResponse>

wp.newCategory

请求

返回

出处:https://www.cnblogs.com/caipeiyu/p/5354341.html

==========================================================================

MetaWeblog API调用

在网上闲逛,突然对博客的接口感兴趣,经考察,多数博客都对metaWeblog Api 提供了支持,虽然windows live writer是好用,不过出于对这个接口的好奇,也想自己做个能发博客的小工具.

到处浏览资料,用了一个下午终于成功发布了一篇简陋版博客:)。其实很简单,方法对了很快就连上了。

MetaWeblog API中文说明

1、什么是MetaWeblog API?

MetaWeblog API(MWA)是一个Blog程序接口标准,允许外部程序来获取或者设置Blog的文字和熟悉。他建立在XMLRPC接口之上,并且已经有了很多的实现。

2、基本的函数规范

有三个基本的函数规范:

metaWeblog.newPost (blogid, username, password, struct, publish) 返回一个字符串,可能是Blog的ID。
metaWeblog.editPost (postid, username, password, struct, publish) 返回一个Boolean值,代表是否修改成功。
metaWeblog.getPost (postid, username, password) 返回一个Struct。

其中blogid、username、password分别代表Blog的id(注释:如果你有两个Blog,blogid指定你需要编辑的blog)、用户名和密码。

一、要引用的DLL【网上提供的示例多包含了这个DLL】

image

二、要实现的数据结构

 MetaWeblogCode【如不想看代码请自行折叠】

复制代码
  1  using System;
  2  using CookComputing.XmlRpc;
  3 
  4  namespace metaWeblogTest
  5  {
  6 
  7      #region 微软MSN网站 使用的 MetaWeblog API.
  8      /// 这个结构代表用户的博客基本信息
  9      ///   </summary>
10      [XmlRpcMissingMapping(MappingAction.Ignore)]
11      public   struct UserBlog
12      {
13          public   string url;
14          public   string blogid;
15          public   string blogName;
16      }
17 
18 
19      ///   <summary>  
20      /// 这个结构代表用户信息
21      ///   </summary>  
22      [XmlRpcMissingMapping(MappingAction.Ignore)]
23      public   struct UserInfo
24      {
25          public   string url;
26          public   string blogid;
27          public   string blogName;
28          public   string firstname;
29          public   string lastname;
30          public   string email;
31          public   string nickname;
32      }
33 
34 
35      ///   <summary>  
36      /// 这个结构代表博客分类信息
37      /// 这后面的getCategories()方法会取到CATEGORY数据。
38      ///   </summary>  
39      [XmlRpcMissingMapping(MappingAction.Ignore)]
40      public   struct Category
41      {
42          public   string description;
43          public   string title;
44      }
45 
46      ///   <summary>  
47      /// 这个结构代表博客( 文章 )信息。
48      /// 这后面的 editPost()方法, getRecentPosts()方法 和 getPost()方法 会取倒POST数据 . 
49      ///   </summary>  
50      [XmlRpcMissingMapping(MappingAction.Ignore)]
51      public   struct Post
52      {
53          public DateTime dateCreated;
54          public   string description;
55          public   string title;
56          public   string postid;
57          public   string [] categories;
58      }
59      #endregion
60 
61 
62      #region 网站:http: // msdn.microsoft.com/en-us/library/aa905670.aspx
63      /// // <summary>  
64      /// // 微软MSN网站 使用的 MetaWeblog API. 
65      /// /  网站: http://msdn.microsoft.com/en-us/library/aa905670.aspx
66      /// // </summary>  
67      public   class M_MetaWeblog : XmlRpcClientProtocol
68      {
69 
70 
71          ///   <summary>  
72          /// Returns the most recent draft and non-draft blog posts sorted in descending order by publish date. 
73          ///   </summary>  
74          ///   <param name="blogid"> This should be the string MyBlog, which indicates that the post is being created in the user’s blog. </param>  
75          ///   <param name="username"> The name of the user’s space. </param>  
76          ///   <param name="password"> The user’s secret word. </param>  
77          ///   <param name="numberOfPosts"> The number of posts to return. The maximum value is 20. </param>  
78          ///   <returns></returns>  
79          /// TODO:得到最近发布的帖子
80          [XmlRpcMethod( " metaWeblog.getRecentPosts " )]
81          public Post[] getRecentPosts(
82          string blogid,
83          string username,
84          string password,
85          int numberOfPosts)
86          {
87 
88              return (Post[]) this .Invoke( " getRecentPosts " , new   object [] { blogid, username, password, numberOfPosts });
89          }
90 
91 
92          ///   <summary>  
93          /// Posts a new entry to a blog. 
94          ///   </summary>  
95          ///   <param name="blogid"> This should be the string MyBlog, which indicates that the post is being created in the user’s blog. </param>  
96          ///   <param name="username"> The name of the user’s space. </param>  
97          ///   <param name="password"> The user’s secret word. </param>  
98          ///   <param name="post"> A struct representing the content to update. </param>  
99          ///   <param name="publish"> If false, this is a draft post. </param>  
100          ///   <returns> The postid of the newly-created post. </returns>  
101          /// TODO:增加一个最新的帖子
102          [XmlRpcMethod( " metaWeblog.newPost " )]
103          public   string newPost(
104          string blogid,
105          string username,
106          string password,
107          Post content,
108          bool publish)
109          {
110 
111              return ( string ) this .Invoke( " newPost " , new   object [] { blogid, username, password, content, publish });
112          }
113 
114          ///   <summary>  
115          /// Edits an existing entry on a blog. 
116          ///   </summary>  
117          ///   <param name="postid"> The ID of the post to update. </param>  
118          ///   <param name="username"> The name of the user’s space. </param>  
119          ///   <param name="password"> The user’s secret word. </param>  
120          ///   <param name="post"> A struct representing the content to update. </param>  
121          ///   <param name="publish"> If false, this is a draft post. </param>  
122          ///   <returns> Always returns true. </returns>  
123          /// TODO:更新一个帖子
124          [XmlRpcMethod( " metaWeblog.editPost " )]
125          public   bool editPost(
126          string postid,
127          string username,
128          string password,
129          Post content,
130          bool publish)
131          {
132 
133              return ( bool ) this .Invoke( " editPost " , new   object [] { postid, username, password, content, publish });
134          }
135 
136          ///   <summary>  
137          /// Deletes a post from the blog. 
138          ///   </summary>  
139          ///   <param name="appKey"> This value is ignored. </param>  
140          ///   <param name="postid"> The ID of the post to update. </param>  
141          ///   <param name="username"> The name of the user’s space. </param>  
142          ///   <param name="password"> The user’s secret word. </param>  
143          ///   <param name="post"> A struct representing the content to update. </param>  
144          ///   <param name="publish"> This value is ignored. </param>  
145          ///   <returns> Always returns true. </returns>  
146          /// TODO:删除一个帖子
147          [XmlRpcMethod( " blogger.deletePost " )]
148          public   bool deletePost(
149          string appKey,
150          string postid,
151          string username,
152          string password,
153          bool publish)
154          {
155 
156              return ( bool ) this .Invoke( " deletePost " , new   object [] { appKey, postid, username, password, publish });
157          }
158 
159 
160          ///   <summary>  
161          /// Returns information about the user’s space. An empty array is returned if the user does not have a space. 
162          ///   </summary>  
163          ///   <param name="appKey"> This value is ignored. </param>  
164          ///   <param name="postid"> The ID of the post to update. </param>  
165          ///   <param name="username"> The name of the user’s space. </param>  
166          ///   <param name="password"></param>
167          ///   <returns> An array of structs that represents each of the user’s blogs. The array will contain a maximum of one struct, since a user can only have a single space with a single blog. </returns>  
168          /// TODO:得到用户的博客清单
169          [XmlRpcMethod( " blogger.getUsersBlogs " )]
170          public UserBlog[] getUsersBlogs(
171          string appKey,
172          string username,
173          string password)
174          {
175 
176              return (UserBlog[]) this .Invoke( " getUsersBlogs " , new   object [] { appKey, username, password });
177          }
178 
179          ///   <summary>  
180          /// Returns basic user info (name, e-mail, userid, and so on). 
181          ///   </summary>  
182          ///   <param name="appKey"> This value is ignored. </param>  
183          ///   <param name="postid"> The ID of the post to update. </param>  
184          ///   <param name="username"> The name of the user’s space. </param>  
185          ///   <param name="password"></param>
186          ///   <returns> A struct containing profile information about the user. 
187          /// Each struct will contain the following fields: nickname, userid, url, e-mail, 
188          /// lastname, and firstname. </returns>  
189          /// TODO:得到用户信息
190          [XmlRpcMethod( " blogger.getUserInfo " )]
191          public UserInfo getUserInfo(
192          string appKey,
193          string username,
194          string password)
195          {
196 
197              return (UserInfo) this .Invoke( " getUserInfo " , new   object [] { appKey, username, password });
198          }
199 
200 
201          ///   <summary>  
202          /// Returns a specific entry from a blog. 
203          ///   </summary>  
204          ///   <param name="postid"> The ID of the post to update. </param>  
205          ///   <param name="username"> The name of the user’s space. </param>  
206          ///   <param name="password"> The user’s secret word. </param>  
207          ///   <returns> Always returns true. </returns>  
208          /// TODO:获取一个帖子
209          [XmlRpcMethod( " metaWeblog.getPost " )]
210          public Post getPost(
211          string postid,
212          string username,
213          string password)
214          {
215 
216              return (Post) this .Invoke( " getPost " , new   object [] { postid, username, password });
217          }
218 
219          ///   <summary>  
220          /// Returns the list of categories that have been used in the blog. 
221          ///   </summary>  
222          ///   <param name="blogid"> This should be the string MyBlog, which indicates that the post is being created in the user’s blog. </param>  
223          ///   <param name="username"> The name of the user’s space. </param>  
224          ///   <param name="password"> The user’s secret word. </param>  
225          ///   <returns> An array of structs that contains one struct for each category. Each category struct will contain a description field that contains the name of the category. </returns>  
226          /// TODO:得到博客分类
227          [XmlRpcMethod( " metaWeblog.getCategories " )]
228          public Category[] getCategories(
229          string blogid,
230          string username,
231          string password)
232          {
233 
234              return (Category[]) this .Invoke( " getCategories " , new   object [] { blogid, username, password });
235          }
236      }
237      #endregion
238  }
239 
复制代码

三、图示【调用API发送第一篇简单博客】

 image

——————————————————————————————————————————

资源链接:

http://www.xmlrpc.com/spec   英文的xml-rpc规范
RFC: MetaWeblog API   MetaWeblog API 规范
http://www.duduwolf.com/post/41.asp  中文翻译的xml-rpc规范(感谢翻译者:滴水)
http://www.XML-RPC.Net XML-RPC的.NET 实现,其中有最新.net2.0的XML-RPC实现的下载
MetaWeblogAPI and MSN Spaces  MSDN上关于MetaWeblog API及MSN Spaces接口的说明及.NET示例

出处:https://www.cnblogs.com/stubman/archive/2011/05/17/1954598.html

========================================================================

使用metawebblog api 实现自己的博客接口

metawebblog api  是一个博客标准,这样我们就可以通过实现这个标准来实现

我们自己的博客支持word2007,windows liver writer来写博客.

metablog的.net接口如下.

using System;
using System.Collections.Generic;
using System.Text;
using CookComputing.XmlRpc;

namespace blog
{

    #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
    {
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember(Description = "Required when posting.")]
        public DateTime dateCreated;
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember(Description = "Required when posting.")]
        public string description;
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember(Description = "Required when posting.")]
        public string title;

        public string[] categories;
        public Enclosure enclosure;
        public string link;
        public string permalink;
        [XmlRpcMember(
             Description = "Not required when posting. Depending on server may "
             + "be either string or integer. "
             + "Use Convert.ToInt32(postid) to treat as integer or "
             + "Convert.ToString(postid) to treat as string")]
        public object postid;
        public Source source;
        public string userid;

        //public string mt_excerpt;
    }

    [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;
    }

    public struct MediaObjectUrl
        {
            public string url;
        }

    public struct MediaObject
        {
            public string name;
            public string type;
            public byte[] bits;
        }
    #endregion
    public interface IMetaWeblog
    {
        #region MetaWeblog API

        [XmlRpcMethod("metaWeblog.newPost",
             Description = "Makes a new post to a designated blog using the "
             + "MetaWeblog API. Returns postid as a string.")]
        string newPost(
            string blogid,
            string username,
            string password,
            Post post,
            bool publish);

        [XmlRpcMethod("metaWeblog.editPost", Description = "Updates and existing post to a designated blog "
             + "using the MetaWeblog API. Returns true if completed.")]
        bool editPost(
            string postid,
            string username,
            string password,
            Post post,
            bool publish);

        [XmlRpcMethod("metaWeblog.getPost",
             Description = "Retrieves an existing post using the MetaWeblog "
             + "API. Returns the MetaWeblog struct.")]
        Post getPost(
            string postid,
            string username,
            string password);

        [XmlRpcMethod("metaWeblog.getCategories",
             Description = "Retrieves a list of valid categories for a post "
             + "using the MetaWeblog API. Returns the MetaWeblog categories "
             + "struct collection.")]
        CategoryInfo[] getCategories(
            string blogid,
            string username,
            string password);

        [XmlRpcMethod("metaWeblog.getRecentPosts",
             Description = "Retrieves a list of the most recent existing post "
             + "using the MetaWeblog API. Returns the MetaWeblog struct collection.")]
        Post[] getRecentPosts(
            string blogid,
            string username,
            string password,
            int numberOfPosts);

        [XmlRpcMethod("metaWeblog.newMediaObject", Description = "Add a media object to a post using the metaWeblog API. Returns media url as a string.")]
        MediaObjectUrl newMediaObject(string blogid, string username, string password, MediaObject mediaObject);

        #endregion

        #region BloggerAPI

        [XmlRpcMethod("blogger.deletePost",
             Description = "Deletes a post.")]
        [return: XmlRpcReturnValue(Description = "Always returns true.")]
        bool deletePost(
            string appKey,
            string postid,
            string username,
            string password,
            [XmlRpcParameter(
                 Description = "Where applicable, this specifies whether the blog "
                 + "should be republished after the post has been deleted.")]
        bool publish);

        [XmlRpcMethod("blogger.getUsersBlogs",
             Description = "Returns information on all the blogs a given user "
             + "is a member.")]
        BlogInfo[] getUsersBlogs(
            string appKey,
            string username,
            string password);

        [XmlRpcMethod("blogger.getUserInfo",
             Description = "Returns information about the given user.")]
        UserInfo getUserInfo(
            string appKey,
            string username,
            string password);

        #endregion

    }

}

 

我们再实现这个接口:

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Data;
using System.IO;
using individual;
using CookComputing.XmlRpc;
using article;
using System.Web;

namespace blog
{
    public class MetaWeblog : XmlRpcService, IMetaWeblog
    {

        #region IMetaWeblog 成员

        public string newPost(string blogid, string username, string password, Post post, bool publish)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");

            ArticleCategory cat = new ArticleCategory();
            DataSet ds= cat.GetAllDSByBlogId(int.Parse(blogid));

            DataTable dt = ds.Tables[0];
            DataRowCollection drs = ds.Tables[0].Rows;

            Article article = new Article();
            ArticleModel model = new ArticleModel();
            model.AddTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            model.BlogId = int.Parse(blogid);
            model.Contents = post.description;
            model.CanRemark = 1;
            model.Subject = post.title;
            model.State = (publish) ? 1 : 2;

            if (post.categories.Length > 0)
            {
                string catName = post.categories[0];
                DataRow[] aryDr = dt.Select("name='" + catName +"'");
                model.CategoryId = int.Parse(aryDr[0]["categoryId"].ToString());
            }
            else
            {
                model.CategoryId = int.Parse(drs[0]["categoryId"].ToString());
            }

            article.Model = model;
            long postId = article.Add();

            if (postId > 0)
                return postId.ToString();
            else
                throw new XmlRpcFaultException(0, "发表文章不成功");

        }

        public bool editPost(string postid, string username, string password, Post post, bool publish)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            try
            {
                Article article = new Article();
                int articleId = int.Parse(postid);
                ArticleModel model = (ArticleModel)article.GetById(articleId);

                model.AddTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
                model.Contents = post.description;
                model.Subject = post.title;
                model.State = (publish) ? 1 : 2;
                if (post.categories.Length > 0)
                {
                    ArticleCategory cat = new ArticleCategory();
                    DataSet ds = cat.GetAllDSByBlogId(model.BlogId);
                    DataTable dt = ds.Tables[0];
                    string catName = post.categories[0];
                    DataRow[] aryDr = dt.Select("name='" + catName +"'");
                    model.CategoryId = int.Parse(aryDr[0]["categoryId"].ToString());
                }
                article.Model = model;
                article.Update();
                return true;
            }
            catch (Exception ex)
            {
                throw new XmlRpcFaultException(0, "更新文章失败");
            }
        }

        public Post getPost(string postid, string username, string password)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            Article article = new Article();
            int articleId = int.Parse(postid);
            ArticleModel model = (ArticleModel)article.GetById(articleId);

            Post post = ConvertModelToPost(model);
            return post;
        }

        public CategoryInfo[] getCategories(string blogid, string username, string password)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            ArticleCategory cat = new ArticleCategory();
            int blogId=int.Parse(blogid);
            DataSet ds= cat.GetAllDSByBlogId(blogId);
            DataRowCollection drs = ds.Tables[0].Rows;
            ArrayList al = new ArrayList(drs.Count);
            foreach (DataRow dr in drs)
            {
                CategoryInfo catInfo = new CategoryInfo();
                catInfo.categoryid = dr["CategoryId"].ToString();
                catInfo.title = dr["name"].ToString();
                catInfo.description = "";
                catInfo.htmlUrl = "";
                catInfo.rssUrl = "";
                al.Add(catInfo);
            }
            return al.ToArray(typeof(CategoryInfo)) as CategoryInfo[];
        }

        public Post[] getRecentPosts(string blogid, string username, string password, int numberOfPosts)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");

            int blogId=int.Parse(blogid);

            Article article = new Article();
            DataSet ds= article.GetAllByBlogId(blogId, 1, numberOfPosts).PageDataSet;

            DataRowCollection drs=ds.Tables[0].Rows;

            ArrayList al = new ArrayList(drs.Count);

            foreach (DataRow dr in drs)
            {
                Post post = new Post();
                post.postid = dr["articleId"].ToString();
                post.title = dr["subject"].ToString();
                post.description = dr["Contents"].ToString();
                post.categories = new string[] { dr["CategoryId"].ToString()};
                al.Add(post);
            }

            return (Post[])al.ToArray(typeof(Post));
        }

        //实现文件上传

        public MediaObjectUrl newMediaObject(string blogid, string username, string password, MediaObject mediaObject)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");

            Blog blog = new Blog();
            BlogModel model = (BlogModel)blog.GetById(int.Parse(blogid));

            string filename =  HttpContext.Current.Server.MapPath("/data/" + model.UserId + "/" + mediaObject.name);
            if (!Directory.Exists(Path.GetDirectoryName(filename)))
                Directory.CreateDirectory(Path.GetDirectoryName(filename));
            File.WriteAllBytes(filename, mediaObject.bits);
            MediaObjectUrl mediaObjectUrl = new MediaObjectUrl();
            mediaObjectUrl.url = "http://博客地址/data/" + model.UserId + "/" + mediaObject.name;
            return mediaObjectUrl;
        }

        public bool deletePost(string appKey, string postid, string username, string password, bool publish)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            Article article = new Article();
            article.Delete(int.Parse(postid));
            return true;
        }

        public BlogInfo[] getUsersBlogs(string appKey, string username, string password)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            Blog blog = new Blog();

            BlogModel model =(BlogModel) blog.GetByNickname(username);
            BlogInfo bloginfo = new BlogInfo();
            bloginfo.blogid = model.BlogId.ToString();
            bloginfo.blogName = username;
            bloginfo.url = http://博客地址/ + username;
            return new BlogInfo[] { bloginfo };
        }

        public UserInfo getUserInfo(string appKey, string username, string password)
        {
            if(!ValidateUser(username,password)) throw new XmlRpcFaultException(0, "用户不存在");
            Individual indi = new Individual();
            IndividualModel model= indi.GetByNickName(username);
            UserInfo userInfo = new UserInfo();
            userInfo.nickname = model.Nickname;
            userInfo.email = model.Account;
            userInfo.userid = model.UserId.ToString();

            return userInfo;
        }

        private Post ConvertModelToPost(ArticleModel model)
        {
            Post post = new Post();
            post.postid = model.ArticleId.ToString();
            post.title = model.Subject;
            post.description = model.Contents;
            post.categories = new string[] { model.CategoryId.ToString() };
            return post;
        }

        private bool ValidateUser(string username, string password)
        {
            try
            {
                bool isLogin = Individual.LoginNickname(username, password);
                return isLogin;
            }
            catch (Exception ex)
            {
                return false;
            }

        }
        #endregion
    }
}

 

 

这样就实现了博客支持客户端写作了

出处:https://www.cnblogs.com/yg_zhang/archive/2007/07/20/825290.html

参考资料:

https://zh.wikipedia.org/wiki/XML-RPC
http://www.cnblogs.com/services/metablogapi.aspx


主要程序接口(来自博客园):

blogger.deletePost —— 删除文章

blogger.getUsersBlogs —— 获取用户博客信息

metaWeblog.editPost —— 编辑文章

metaWeblog.getCategories —— 获取用户博客分类

metaWeblog.getPost —— 获取文章

metaWeblog.getRecentPosts —— 获取最近的文章

metaWeblog.newMediaObject —— 添加媒体对象(图片等)

metaWeblog.newPost —— 添加文章

wp.newCategory —— 添加目录

接口说明


blogger.deletePost

请求

<?xml version="1.0"?>
<methodCall>
  <methodName>blogger.deletePost</methodName>
  <params>
    <param>
        <value><string>appkey</string></value>
    </param>
    <param>
        <value><string>postid</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
    <param>
        <value><boolean>0</boolean></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <boolean>1</boolean>
            </value>
        </param>
    </params>
</methodResponse>

blogger.getUsersBlogs

请求

<?xml version="1.0"?>
<methodCall>
  <methodName>blogger.getUsersBlogs</methodName>
  <params>
    <param>
        <value><string>appkey</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <array>
                    <data>
                        <value>
                            <struct>
                                <member>
                                    <name>blogid</name>
                                    <value>
                                        <string>dsafds</string>
                                    </value>
                                </member>
                                <member>
                                    <name>url</name>
                                    <value>
                                        <string>http://www.cnblogs.com/caipeiyu/</string>
                                    </value>
                                </member>
                                <member>
                                    <name>blogName</name>
                                    <value>
                                        <string>蛀牙</string>
                                    </value>
                                </member>
                            </struct>
                        </value>
                    </data>
                </array>
            </value>
        </param>
    </params>
</methodResponse>

metaWeblog.editPost

请求

返回


metaWeblog.getCategories

请求

返回


metaWeblog.getPost
请求

<?xml version="1.0"?>
    <methodCall>
      <methodName>blogger.getUsersBlogs</methodName>
      <params>
        <param>
            <value><string>postid</string></value>
        </param>
        <param>
            <value><string>username</string></value>
        </param>
        <param>
            <value><string>password</string></value>
        </param>
      </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <struct>
                    <member>
                        <name>dateCreated</name>
                        <value>
                            <dateTime.iso8601>时间</dateTime.iso8601>
                        </value>
                    </member>
                    <member>
                        <name>description</name>
                        <value>
                            <string>博客内容</string>
                        </value>
                    </member>
                    <member>
                        <name>title</name>
                        <value>
                            <string>标题内容</string>
                        </value>
                    </member>
                    <member>
                        <name>categories</name>
                        <value>
                            <array>
                                <data>
                                    <value>
                                        <string>[Markdown]</string>
                                    </value>
                                </data>
                            </array>
                        </value>
                    </member>
                    <member>
                        <name>enclosure</name>
                        <value>
                            <struct>
                                <member>
                                    <name>length</name>
                                    <value>
                                        <i4>0</i4>
                                    </value>
                                </member>
                            </struct>         
                        </value>
                    </member>
                    <member>
                        <name>link</name>
                        <value>
                            <string>http://.html</string>
                        </value>
                    </member>
                    <member>
                        <name>permalink</name>
                        <value>
                            <string>http://.html</string>
                        </value>
                    </member>
                    <member>
                        <name>postid</name>
                        <value>
                            <i4>00000</i4>
                        </value>
                    </member>
                    <member>
                        <name>source</name>
                        <value>
                            <struct />
                        </value>
                    </member>
                    <member>
                        <name>mt_keywords</name>
                        <value>
                            <string />
                        </value>
                    </member>
                </struct> 
            </value>
        </param>
    </params>
</methodResponse>

metaWeblog.getRecentPosts

请求

<?xml version="1.0"?>
<methodCall>
  <methodName>metaWeblog.getRecentPosts</methodName>
  <params>
    <param>
        <value><string>000000</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
    
    <param>
        <value><i4>10</i4></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <array>
                    <data>
                        <value>
                            <struct>
                                <member>
                                    <name>dateCreated</name>
                                    <value>
                                        <dateTime.iso8601>20160405T18:32:00</dateTime.iso8601>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>description</name>
                                    <value>
                                        <string>博客测试内容</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>title</name>
                                    <value>
                                        <string>标题测试内容</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>enclosure</name>
                                    <value>
                                        <struct>
                                            <member>
                                                <name>length</name>
                                                <value>
                                                    <i4>0</i4>
                        
                                                </value>
                      
                                            </member>
                    
                                        </struct>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>link</name>
                                    <value>
                                        <string>http://www.cnblogs.com/caipeiyu/p/5356274.html</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>permalink</name>
                                    <value>
                                        <string>http://www.cnblogs.com/caipeiyu/p/5356274.html</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>postid</name>
                                    <value>
                                        <string>5356274</string>
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>source</name>
                                    <value>
                                        <struct />
                  
                                    </value>
                
                                </member>
                                <member>
                                    <name>userid</name>
                                    <value>
                                        <string>-2</string>
                  
                                    </value>
                
                                </member>
              
                            </struct>
            
                        </value>

          
                    </data>
        
                </array>
      
            </value>
    
        </param>
  
    </params>

</methodResponse>   

metaWeblog.newMediaObject

请求

返回


metaWeblog.newPost

请求
这个请求内容标题和内容是必须的,其他可以选填

<?xml version="1.0"?>
<methodCall>
  <methodName>metaWeblog.newPost</methodName>
  <params>
    <param>
        <value><string>postid</string></value>
    </param>
    <param>
        <value><string>username</string></value>
    </param>
    <param>
        <value><string>password</string></value>
    </param>
    <param>
         <value>
                <struct>
                    <member>
                        <name>description</name>
                        <value>
                            <string>博客测试内容</string>
                        </value>
                    </member>
                    <member>
                        <name>title</name>
                        <value>
                            <string>标题测试内容</string>
                        </value>
                    </member>
                    <member>
                        <name>categories</name>
                        <value>
                            <array>
                                <data>
                                    <value>
                                        <string>[Markdown]</string>
                                    </value>
                                </data>
                            </array>
                        </value>
                    </member>
                </struct> 
            </value>
    </param>
    <param>
        <value><boolean>0</boolean></value>
    </param>
  </params>
</methodCall>

返回

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <string>000000</string>
            </value>
        </param>
    </params>
</methodResponse>

wp.newCategory

请求

返回

在网上闲逛,突然对博客的接口感兴趣,经考察,多数博客都对metaWeblog Api 提供了支持,虽然windows live writer是好用,不过出于对这个接口的好奇,也想自己做个能发博客的小工具.

到处浏览资料,用了一个下午终于成功发布了一篇简陋版博客:)。其实很简单,方法对了很快就连上了。

MetaWeblog API中文说明

1、什么是MetaWeblog API?

MetaWeblog API(MWA)是一个Blog程序接口标准,允许外部程序来获取或者设置Blog的文字和熟悉。他建立在XMLRPC接口之上,并且已经有了很多的实现。

2、基本的函数规范

有三个基本的函数规范:

metaWeblog.newPost (blogid, username, password, struct, publish) 返回一个字符串,可能是Blog的ID。
metaWeblog.editPost (postid, username, password, struct, publish) 返回一个Boolean值,代表是否修改成功。
metaWeblog.getPost (postid, username, password) 返回一个Struct。

其中blogid、username、password分别代表Blog的id(注释:如果你有两个Blog,blogid指定你需要编辑的blog)、用户名和密码。

一、要引用的DLL【网上提供的示例多包含了这个DLL】

image

二、要实现的数据结构

 MetaWeblogCode【如不想看代码请自行折叠】

复制代码
  1  using System;
  2  using CookComputing.XmlRpc;
  3 
  4  namespace metaWeblogTest
  5  {
  6 
  7      #region 微软MSN网站 使用的 MetaWeblog API.
  8      /// 这个结构代表用户的博客基本信息
  9      ///   </summary>
10      [XmlRpcMissingMapping(MappingAction.Ignore)]
11      public   struct UserBlog
12      {
13          public   string url;
14          public   string blogid;
15          public   string blogName;
16      }
17 
18 
19      ///   <summary>  
20      /// 这个结构代表用户信息
21      ///   </summary>  
22      [XmlRpcMissingMapping(MappingAction.Ignore)]
23      public   struct UserInfo
24      {
25          public   string url;
26          public   string blogid;
27          public   string blogName;
28          public   string firstname;
29          public   string lastname;
30          public   string email;
31          public   string nickname;
32      }
33 
34 
35      ///   <summary>  
36      /// 这个结构代表博客分类信息
37      /// 这后面的getCategories()方法会取到CATEGORY数据。
38      ///   </summary>  
39      [XmlRpcMissingMapping(MappingAction.Ignore)]
40      public   struct Category
41      {
42          public   string description;
43          public   string title;
44      }
45 
46      ///   <summary>  
47      /// 这个结构代表博客( 文章 )信息。
48      /// 这后面的 editPost()方法, getRecentPosts()方法 和 getPost()方法 会取倒POST数据 . 
49      ///   </summary>  
50      [XmlRpcMissingMapping(MappingAction.Ignore)]
51      public   struct Post
52      {
53          public DateTime dateCreated;
54          public   string description;
55          public   string title;
56          public   string postid;
57          public   string [] categories;
58      }
59      #endregion
60 
61 
62      #region 网站:http: // msdn.microsoft.com/en-us/library/aa905670.aspx
63      /// // <summary>  
64      /// // 微软MSN网站 使用的 MetaWeblog API. 
65      /// /  网站: http://msdn.microsoft.com/en-us/library/aa905670.aspx
66      /// // </summary>  
67      public   class M_MetaWeblog : XmlRpcClientProtocol
68      {
69 
70 
71          ///   <summary>  
72          /// Returns the most recent draft and non-draft blog posts sorted in descending order by publish date. 
73          ///   </summary>  
74          ///   <param name="blogid"> This should be the string MyBlog, which indicates that the post is being created in the user’s blog. </param>  
75          ///   <param name="username"> The name of the user’s space. </param>  
76          ///   <param name="password"> The user’s secret word. </param>  
77          ///   <param name="numberOfPosts"> The number of posts to return. The maximum value is 20. </param>  
78          ///   <returns></returns>  
79          /// TODO:得到最近发布的帖子
80          [XmlRpcMethod( " metaWeblog.getRecentPosts " )]
81          public Post[] getRecentPosts(
82          string blogid,
83          string username,
84          string password,
85          int numberOfPosts)
86          {
87 
88              return (Post[]) this .Invoke( " getRecentPosts " , new   object [] { blogid, username, password, numberOfPosts });
89          }
90 
91 
92          ///   <summary>  
93          /// Posts a new entry to a blog. 
94          ///   </summary>  
95          ///   <param name="blogid"> This should be the string MyBlog, which indicates that the post is being created in the user’s blog. </param>  
96          ///   <param name="username"> The name of the user’s space. </param>  
97          ///   <param name="password"> The user’s secret word. </param>  
98          ///   <param name="post"> A struct representing the content to update. </param>  
99          ///   <param name="publish"> If false, this is a draft post. </param>  
100          ///   <returns> The postid of the newly-created post. </returns>  
101          /// TODO:增加一个最新的帖子
102          [XmlRpcMethod( " metaWeblog.newPost " )]
103          public   string newPost(
104          string blogid,
105          string username,
106          string password,
107          Post content,
108          bool publish)
109          {
110 
111              return ( string ) this .Invoke( " newPost " , new   object [] { blogid, username, password, content, publish });
112          }
113 
114          ///   <summary>  
115          /// Edits an existing entry on a blog. 
116          ///   </summary>  
117          ///   <param name="postid"> The ID of the post to update. </param>  
118          ///   <param name="username"> The name of the user’s space. </param>  
119          ///   <param name="password"> The user’s secret word. </param>  
120          ///   <param name="post"> A struct representing the content to update. </param>  
121          ///   <param name="publish"> If false, this is a draft post. </param>  
122          ///   <returns> Always returns true. </returns>  
123          /// TODO:更新一个帖子
124          [XmlRpcMethod( " metaWeblog.editPost " )]
125          public   bool editPost(
126          string postid,
127          string username,
128          string password,
129          Post content,
130          bool publish)
131          {
132 
133              return ( bool ) this .Invoke( " editPost " , new   object [] { postid, username, password, content, publish });
134          }
135 
136          ///   <summary>  
137          /// Deletes a post from the blog. 
138          ///   </summary>  
139          ///   <param name="appKey"> This value is ignored. </param>  
140          ///   <param name="postid"> The ID of the post to update. </param>  
141          ///   <param name="username"> The name of the user’s space. </param>  
142          ///   <param name="password"> The user’s secret word. </param>  
143          ///   <param name="post"> A struct representing the content to update. </param>  
144          ///   <param name="publish"> This value is ignored. </param>  
145          ///   <returns> Always returns true. </returns>  
146          /// TODO:删除一个帖子
147          [XmlRpcMethod( " blogger.deletePost " )]
148          public   bool deletePost(
149          string appKey,
150          string postid,
151          string username,
152          string password,
153          bool publish)
154          {
155 
156              return ( bool ) this .Invoke( " deletePost " , new   object [] { appKey, postid, username, password, publish });
157          }
158 
159 
160          ///   <summary>  
161          /// Returns information about the user’s space. An empty array is returned if the user does not have a space. 
162          ///   </summary>  
163          ///   <param name="appKey"> This value is ignored. </param>  
164          ///   <param name="postid"> The ID of the post to update. </param>  
165          ///   <param name="username"> The name of the user’s space. </param>  
166          ///   <param name="password"></param>
167          ///   <returns> An array of structs that represents each of the user’s blogs. The array will contain a maximum of one struct, since a user can only have a single space with a single blog. </returns>  
168          /// TODO:得到用户的博客清单
169          [XmlRpcMethod( " blogger.getUsersBlogs " )]
170          public UserBlog[] getUsersBlogs(
171          string appKey,
172          string username,
173          string password)
174          {
175 
176              return (UserBlog[]) this .Invoke( " getUsersBlogs " , new   object [] { appKey, username, password });
177          }
178 
179          ///   <summary>  
180          /// Returns basic user info (name, e-mail, userid, and so on). 
181          ///   </summary>  
182          ///   <param name="appKey"> This value is ignored. </param>  
183          ///   <param name="postid"> The ID of the post to update. </param>  
184          ///   <param name="username"> The name of the user’s space. </param>  
185          ///   <param name="password"></param>
186          ///   <returns> A struct containing profile information about the user. 
187          /// Each struct will contain the following fields: nickname, userid, url, e-mail, 
188          /// lastname, and firstname. </returns>  
189          /// TODO:得到用户信息
190          [XmlRpcMethod( " blogger.getUserInfo " )]
191          public UserInfo getUserInfo(
192          string appKey,
193          string username,
194          string password)
195          {
196 
197              return (UserInfo) this .Invoke( " getUserInfo " , new   object [] { appKey, username, password });
198          }
199 
200 
201          ///   <summary>  
202          /// Returns a specific entry from a blog. 
203          ///   </summary>  
204          ///   <param name="postid"> The ID of the post to update. </param>  
205          ///   <param name="username"> The name of the user’s space. </param>  
206          ///   <param name="password"> The user’s secret word. </param>  
207          ///   <returns> Always returns true. </returns>  
208          /// TODO:获取一个帖子
209          [XmlRpcMethod( " metaWeblog.getPost " )]
210          public Post getPost(
211          string postid,
212          string username,
213          string password)
214          {
215 
216              return (Post) this .Invoke( " getPost " , new   object [] { postid, username, password });
217          }
218 
219          ///   <summary>  
220          /// Returns the list of categories that have been used in the blog. 
221          ///   </summary>  
222          ///   <param name="blogid"> This should be the string MyBlog, which indicates that the post is being created in the user’s blog. </param>  
223          ///   <param name="username"> The name of the user’s space. </param>  
224          ///   <param name="password"> The user’s secret word. </param>  
225          ///   <returns> An array of structs that contains one struct for each category. Each category struct will contain a description field that contains the name of the category. </returns>  
226          /// TODO:得到博客分类
227          [XmlRpcMethod( " metaWeblog.getCategories " )]
228          public Category[] getCategories(
229          string blogid,
230          string username,
231          string password)
232          {
233 
234              return (Category[]) this .Invoke( " getCategories " , new   object [] { blogid, username, password });
235          }
236      }
237      #endregion
238  }
239 
复制代码

三、图示【调用API发送第一篇简单博客】

 image

——————————————————————————————————————————

资源链接:

http://www.xmlrpc.com/spec   英文的xml-rpc规范
RFC: MetaWeblog API   MetaWeblog API 规范
http://www.duduwolf.com/post/41.asp  中文翻译的xml-rpc规范(感谢翻译者:滴水)
http://www.XML-RPC.Net XML-RPC的.NET 实现,其中有最新.net2.0的XML-RPC实现的下载
MetaWeblogAPI and MSN Spaces  MSDN上关于MetaWeblog API及MSN Spaces接口的说明及.NET示例

metawebblog api  是一个博客标准,这样我们就可以通过实现这个标准来实现

我们自己的博客支持word2007,windows liver writer来写博客.

metablog的.net接口如下.

using System;
using System.Collections.Generic;
using System.Text;
using CookComputing.XmlRpc;

namespace blog
{

    #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
    {
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember(Description = "Required when posting.")]
        public DateTime dateCreated;
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember(Description = "Required when posting.")]
        public string description;
        [XmlRpcMissingMapping(MappingAction.Error)]
        [XmlRpcMember(Description = "Required when posting.")]
        public string title;

        public string[] categories;
        public Enclosure enclosure;
        public string link;
        public string permalink;
        [XmlRpcMember(
             Description = "Not required when posting. Depending on server may "
             + "be either string or integer. "
             + "Use Convert.ToInt32(postid) to treat as integer or "
             + "Convert.ToString(postid) to treat as string")]
        public object postid;
        public Source source;
        public string userid;

        //public string mt_excerpt;
    }

    [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;
    }

    public struct MediaObjectUrl
        {
            public string url;
        }

    public struct MediaObject
        {
            public string name;
            public string type;
            public byte[] bits;
        }
    #endregion
    public interface IMetaWeblog
    {
        #region MetaWeblog API

        [XmlRpcMethod("metaWeblog.newPost",
             Description = "Makes a new post to a designated blog using the "
             + "MetaWeblog API. Returns postid as a string.")]
        string newPost(
            string blogid,
            string username,
            string password,
            Post post,
            bool publish);

        [XmlRpcMethod("metaWeblog.editPost", Description = "Updates and existing post to a designated blog "
             + "using the MetaWeblog API. Returns true if completed.")]
        bool editPost(
            string postid,
            string username,
            string password,
            Post post,
            bool publish);

        [XmlRpcMethod("metaWeblog.getPost",
             Description = "Retrieves an existing post using the MetaWeblog "
             + "API. Returns the MetaWeblog struct.")]
        Post getPost(
            string postid,
            string username,
            string password);

        [XmlRpcMethod("metaWeblog.getCategories",
             Description = "Retrieves a list of valid categories for a post "
             + "using the MetaWeblog API. Returns the MetaWeblog categories "
             + "struct collection.")]
        CategoryInfo[] getCategories(
            string blogid,
            string username,
            string password);

        [XmlRpcMethod("metaWeblog.getRecentPosts",
             Description = "Retrieves a list of the most recent existing post "
             + "using the MetaWeblog API. Returns the MetaWeblog struct collection.")]
        Post[] getRecentPosts(
            string blogid,
            string username,
            string password,
            int numberOfPosts);

        [XmlRpcMethod("metaWeblog.newMediaObject", Description = "Add a media object to a post using the metaWeblog API. Returns media url as a string.")]
        MediaObjectUrl newMediaObject(string blogid, string username, string password, MediaObject mediaObject);

        #endregion

        #region BloggerAPI

        [XmlRpcMethod("blogger.deletePost",
             Description = "Deletes a post.")]
        [return: XmlRpcReturnValue(Description = "Always returns true.")]
        bool deletePost(
            string appKey,
            string postid,
            string username,
            string password,
            [XmlRpcParameter(
                 Description = "Where applicable, this specifies whether the blog "
                 + "should be republished after the post has been deleted.")]
        bool publish);

        [XmlRpcMethod("blogger.getUsersBlogs",
             Description = "Returns information on all the blogs a given user "
             + "is a member.")]
        BlogInfo[] getUsersBlogs(
            string appKey,
            string username,
            string password);

        [XmlRpcMethod("blogger.getUserInfo",
             Description = "Returns information about the given user.")]
        UserInfo getUserInfo(
            string appKey,
            string username,
            string password);

        #endregion

    }

}

 

我们再实现这个接口:

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Data;
using System.IO;
using individual;
using CookComputing.XmlRpc;
using article;
using System.Web;

namespace blog
{
    public class MetaWeblog : XmlRpcService, IMetaWeblog
    {

        #region IMetaWeblog 成员

        public string newPost(string blogid, string username, string password, Post post, bool publish)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");

            ArticleCategory cat = new ArticleCategory();
            DataSet ds= cat.GetAllDSByBlogId(int.Parse(blogid));

            DataTable dt = ds.Tables[0];
            DataRowCollection drs = ds.Tables[0].Rows;

            Article article = new Article();
            ArticleModel model = new ArticleModel();
            model.AddTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            model.BlogId = int.Parse(blogid);
            model.Contents = post.description;
            model.CanRemark = 1;
            model.Subject = post.title;
            model.State = (publish) ? 1 : 2;

            if (post.categories.Length > 0)
            {
                string catName = post.categories[0];
                DataRow[] aryDr = dt.Select("name='" + catName +"'");
                model.CategoryId = int.Parse(aryDr[0]["categoryId"].ToString());
            }
            else
            {
                model.CategoryId = int.Parse(drs[0]["categoryId"].ToString());
            }

            article.Model = model;
            long postId = article.Add();

            if (postId > 0)
                return postId.ToString();
            else
                throw new XmlRpcFaultException(0, "发表文章不成功");

        }

        public bool editPost(string postid, string username, string password, Post post, bool publish)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            try
            {
                Article article = new Article();
                int articleId = int.Parse(postid);
                ArticleModel model = (ArticleModel)article.GetById(articleId);

                model.AddTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
                model.Contents = post.description;
                model.Subject = post.title;
                model.State = (publish) ? 1 : 2;
                if (post.categories.Length > 0)
                {
                    ArticleCategory cat = new ArticleCategory();
                    DataSet ds = cat.GetAllDSByBlogId(model.BlogId);
                    DataTable dt = ds.Tables[0];
                    string catName = post.categories[0];
                    DataRow[] aryDr = dt.Select("name='" + catName +"'");
                    model.CategoryId = int.Parse(aryDr[0]["categoryId"].ToString());
                }
                article.Model = model;
                article.Update();
                return true;
            }
            catch (Exception ex)
            {
                throw new XmlRpcFaultException(0, "更新文章失败");
            }
        }

        public Post getPost(string postid, string username, string password)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            Article article = new Article();
            int articleId = int.Parse(postid);
            ArticleModel model = (ArticleModel)article.GetById(articleId);

            Post post = ConvertModelToPost(model);
            return post;
        }

        public CategoryInfo[] getCategories(string blogid, string username, string password)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            ArticleCategory cat = new ArticleCategory();
            int blogId=int.Parse(blogid);
            DataSet ds= cat.GetAllDSByBlogId(blogId);
            DataRowCollection drs = ds.Tables[0].Rows;
            ArrayList al = new ArrayList(drs.Count);
            foreach (DataRow dr in drs)
            {
                CategoryInfo catInfo = new CategoryInfo();
                catInfo.categoryid = dr["CategoryId"].ToString();
                catInfo.title = dr["name"].ToString();
                catInfo.description = "";
                catInfo.htmlUrl = "";
                catInfo.rssUrl = "";
                al.Add(catInfo);
            }
            return al.ToArray(typeof(CategoryInfo)) as CategoryInfo[];
        }

        public Post[] getRecentPosts(string blogid, string username, string password, int numberOfPosts)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");

            int blogId=int.Parse(blogid);

            Article article = new Article();
            DataSet ds= article.GetAllByBlogId(blogId, 1, numberOfPosts).PageDataSet;

            DataRowCollection drs=ds.Tables[0].Rows;

            ArrayList al = new ArrayList(drs.Count);

            foreach (DataRow dr in drs)
            {
                Post post = new Post();
                post.postid = dr["articleId"].ToString();
                post.title = dr["subject"].ToString();
                post.description = dr["Contents"].ToString();
                post.categories = new string[] { dr["CategoryId"].ToString()};
                al.Add(post);
            }

            return (Post[])al.ToArray(typeof(Post));
        }

        //实现文件上传

        public MediaObjectUrl newMediaObject(string blogid, string username, string password, MediaObject mediaObject)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");

            Blog blog = new Blog();
            BlogModel model = (BlogModel)blog.GetById(int.Parse(blogid));

            string filename =  HttpContext.Current.Server.MapPath("/data/" + model.UserId + "/" + mediaObject.name);
            if (!Directory.Exists(Path.GetDirectoryName(filename)))
                Directory.CreateDirectory(Path.GetDirectoryName(filename));
            File.WriteAllBytes(filename, mediaObject.bits);
            MediaObjectUrl mediaObjectUrl = new MediaObjectUrl();
            mediaObjectUrl.url = "http://博客地址/data/" + model.UserId + "/" + mediaObject.name;
            return mediaObjectUrl;
        }

        public bool deletePost(string appKey, string postid, string username, string password, bool publish)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            Article article = new Article();
            article.Delete(int.Parse(postid));
            return true;
        }

        public BlogInfo[] getUsersBlogs(string appKey, string username, string password)
        {
            if (!ValidateUser(username, password)) throw new XmlRpcFaultException(0, "用户不存在");
            Blog blog = new Blog();

            BlogModel model =(BlogModel) blog.GetByNickname(username);
            BlogInfo bloginfo = new BlogInfo();
            bloginfo.blogid = model.BlogId.ToString();
            bloginfo.blogName = username;
            bloginfo.url = http://博客地址/ + username;
            return new BlogInfo[] { bloginfo };
        }

        public UserInfo getUserInfo(string appKey, string username, string password)
        {
            if(!ValidateUser(username,password)) throw new XmlRpcFaultException(0, "用户不存在");
            Individual indi = new Individual();
            IndividualModel model= indi.GetByNickName(username);
            UserInfo userInfo = new UserInfo();
            userInfo.nickname = model.Nickname;
            userInfo.email = model.Account;
            userInfo.userid = model.UserId.ToString();

            return userInfo;
        }

        private Post ConvertModelToPost(ArticleModel model)
        {
            Post post = new Post();
            post.postid = model.ArticleId.ToString();
            post.title = model.Subject;
            post.description = model.Contents;
            post.categories = new string[] { model.CategoryId.ToString() };
            return post;
        }

        private bool ValidateUser(string username, string password)
        {
            try
            {
                bool isLogin = Individual.LoginNickname(username, password);
                return isLogin;
            }
            catch (Exception ex)
            {
                return false;
            }

        }
        #endregion
    }
}

 

 

这样就实现了博客支持客户端写作了

猜你喜欢

转载自www.cnblogs.com/mq0036/p/12766789.html