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>
</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>

</value>

</member>
<member>
<name>permalink</name>
<value>
<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调用



在网上闲逛,突然对博客的接口感兴趣,经考察,多数博客都对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】

​​XML-RPC简单理解与MetaWeblog协议_xml​​

二、要实现的数据结构

 XML-RPC简单理解与MetaWeblog协议_taro_02MetaWeblogCode【如不想看代码请自行折叠】



XML-RPC简单理解与MetaWeblog协议_taro_03



  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 

XML-RPC简单理解与MetaWeblog协议_.net_04


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

 ​​XML-RPC简单理解与MetaWeblog协议_taro_05​​

资源链接:


blog 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://+ 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 =  + 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

    }

}

 

 

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


 

 


主要程序接口:

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>
</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>

</value>

</member>
<member>
<name>permalink</name>
<value>
<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】

​​XML-RPC简单理解与MetaWeblog协议_xml​​

二、要实现的数据结构

 XML-RPC简单理解与MetaWeblog协议_taro_02MetaWeblogCode【如不想看代码请自行折叠】



XML-RPC简单理解与MetaWeblog协议_html_08



  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 

XML-RPC简单理解与MetaWeblog协议_taro_09


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

 ​​XML-RPC简单理解与MetaWeblog协议_taro_05​​

 

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:/​​ + 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 =  + 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

    }

}

 

 

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