新浪微博開放平臺開發(fā)步驟簡介(適合新手看)
我也是個新手,也是第一次使用開放平臺做開發(fā),剛開始感到無處下手,經(jīng)過半天的摸索終于成功的調(diào)用了API,現(xiàn)在把這點經(jīng)驗介紹給新手(高手就沒必要看了,當然,如果你能提些意見和建議,我感激不盡),愿同大家一起交流。
本例介紹的是如何用API提交數(shù)據(jù)(發(fā)布一條微博)和用API獲取數(shù)據(jù)(獲取最新更新的20條公共微博消息),也就是官方API中的“獲取下行數(shù)據(jù)集(timeline)接口”下的“statuses/public_timeline 獲取最新更新的公共微博消息”和“微博訪問接口”下的“statuses/update 發(fā)布一條微博信息”。
首先你要有一個新浪微博帳號,還要申請一個app key(具體請參考http://open.t.sina.com.cn/wiki/index.php/%E6%96%B0%E6%89%8B%E6%8C%87%E5%8D%97),然后在VS中新建一個解決方案,在解決方案中添加一個類庫和一個網(wǎng)站,并添加引用(網(wǎng)站引用類庫)。

由于發(fā)布微博是POST請求,獲取數(shù)據(jù)是GET請求,且通過HTTP普通驗證(Basic Authentication)方式授權(quán),因此我把這些功能寫在一個類中(放在類庫中),代碼如下(這個類參考了http://www.rzrgm.cn/cmt/archive/2010/05/13/1733904.html,沒有仔細考慮是否達到了通用):
發(fā)送請求及授權(quán)代碼
using System.Net;
using System.IO;
namespace SinaMiniBlogLib
{
public class SendRequest
{
string username;
string password;
string key;
public string UsernamePassword
{
get { return username + ":" + password; }
}
#region 構(gòu)造函數(shù)
public SendRequest()
{
username = "你的新浪微博帳號";
password = "你的新浪微博密碼";
key = "你申請的app key";
}
public SendRequest(string username, string password,string key)
{
this.username = username;
this.password = password;
this.key = key;
}
#endregion
#region 發(fā)送GET請求
/// <summary>
/// 發(fā)送GET請求
/// </summary>
/// <param name="url">地址</param>
/// <returns>string</returns>
public string SendGetRequest(string url)
{
string Content=string.Empty;
//準備用于發(fā)起請求的HttpWebRequest對象:
WebRequest webRequest = WebRequest.Create(url+"?source="+key);
HttpWebRequest httpRequest = webRequest as HttpWebRequest;
//準備用于用戶驗證的憑據(jù)
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
httpRequest.Credentials = myCache;
httpRequest.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new System.Text.ASCIIEncoding().GetBytes(UsernamePassword)));
//GET方法
httpRequest.Method = "GET";
HttpWebResponse httpRespone = (HttpWebResponse)httpRequest.GetResponse();
if (httpRespone != null && httpRespone.StatusCode == HttpStatusCode.OK)
{
using (StreamReader sr = new StreamReader(httpRespone.GetResponseStream()))
{
Content = sr.ReadToEnd();
}
}
return Content;
}
#endregion
#region 發(fā)送POST請求
/// <summary>
/// 發(fā)送POST請求
/// </summary>
/// <param name="url">網(wǎng)址</param>
/// <param name="Content">內(nèi)容</param>
/// <returns>string</returns>
public string SendPostRequest(string url,string Content)
{
string result = string.Empty;
//準備調(diào)用的URL及需要POST的數(shù)據(jù):
string data = "source="+key+"&status=" + Content;
//準備用于發(fā)起請求的HttpWebRequest對象:
WebRequest webRequest = WebRequest.Create(url);
HttpWebRequest httpRequest = webRequest as HttpWebRequest;
//準備用于用戶驗證的憑據(jù)
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
httpRequest.Credentials = myCache;
httpRequest.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new System.Text.ASCIIEncoding().GetBytes(UsernamePassword)));
//發(fā)起POST請求
httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded";
System.Text.Encoding encoding = System.Text.Encoding.ASCII;
byte[] bytesToPost = encoding.GetBytes(data);
httpRequest.ContentLength = bytesToPost.Length;
System.IO.Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(bytesToPost, 0, bytesToPost.Length);
requestStream.Close();
//獲取服務(wù)端的響應內(nèi)容
System.Net.WebResponse wr = httpRequest.GetResponse();
System.IO.Stream receiveStream = wr.GetResponseStream();
using (System.IO.StreamReader reader = new System.IO.StreamReader(receiveStream, System.Text.Encoding.UTF8))
{
result = reader.ReadToEnd();
}
return result;
}
#endregion
}
}
然后在類庫中新建兩個實體類status和user,字段與官方API中一致:
status實體類
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SinaMiniBlogLib
{
public class status
{
public status()
{
user = new user();
}
#region 屬性
private DateTime created_at;
private string id;
private string text;
private string source;
private bool favorited;
private bool truncated;
private string in_reply_to_status_id;
private string in_reply_to_user_id;
private string in_reply_to_screen_name;
private string thumbnail_pic;
private string bmiddle_pic;
private string original_pic;
private user user;
private status retweeted_status;
#endregion
#region 屬性封裝
/// <summary>
/// 創(chuàng)建時間
/// </summary>
public DateTime Created_at
{
get { return created_at; }
set { created_at = value; }
}
/// <summary>
/// 微博ID
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
/// <summary>
/// 微博信息內(nèi)容
/// </summary>
public string Text
{
get { return text; }
set { text = value; }
}
/// <summary>
/// 微博來源
/// </summary>
public string Source
{
get { return source; }
set { source = value; }
}
/// <summary>
/// 是否已收藏
/// </summary>
public bool Favorited
{
get { return favorited; }
set { favorited = value; }
}
/// <summary>
/// 是否被截斷
/// </summary>
public bool Truncated
{
get { return truncated; }
set { truncated = value; }
}
/// <summary>
/// 回復ID
/// </summary>
public string In_reply_to_status_id
{
get { return in_reply_to_status_id; }
set { in_reply_to_status_id = value; }
}
/// <summary>
/// 回復人UID
/// </summary>
public string In_reply_to_user_id
{
get { return in_reply_to_user_id; }
set { in_reply_to_user_id = value; }
}
/// <summary>
/// 回復人昵稱
/// </summary>
public string In_reply_to_screen_name
{
get { return in_reply_to_screen_name; }
set { in_reply_to_screen_name = value; }
}
/// <summary>
/// 縮略圖
/// </summary>
public string Thumbnail_pic
{
get { return thumbnail_pic; }
set { thumbnail_pic = value; }
}
/// <summary>
/// 中型圖片
/// </summary>
public string Bmiddle_pic
{
get { return bmiddle_pic; }
set { bmiddle_pic = value; }
}
/// <summary>
/// 原始圖片
/// </summary>
public string Original_pic
{
get { return original_pic; }
set { original_pic = value; }
}
/// <summary>
/// 作者信息
/// </summary>
public user User
{
get { return user; }
set { user = value; }
}
/// <summary>
/// 轉(zhuǎn)發(fā)的博文,內(nèi)容為status,如果不是轉(zhuǎn)發(fā),則沒有此字段
/// </summary>
public status Retweeted_status
{
get { return retweeted_status; }
set { retweeted_status = value; }
}
#endregion
}
}
user實體類
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SinaMiniBlogLib
{
public class user
{
#region 屬性
private string id;
private string screen_name;
private string name;
private int province;
private int city;
private string location;
private string description;
private string url;
private string profile_image_url;
private string domain;
private string gender;
private int followers_count;
private int friends_count;
private int statuses_count;
private int favourites_count;
private DateTime created_at;
private bool following;
private bool verified;
#endregion
#region 屬性封裝
/// <summary>
/// 用戶UID
/// </summary>
public string Id
{
get { return id; }
set { id = value; }
}
/// <summary>
/// 微博昵稱
/// </summary>
public string Screen_name
{
get { return screen_name; }
set { screen_name = value; }
}
/// <summary>
/// 友好顯示名稱,如Bill Gates(此特性暫不支持)
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
/// <summary>
/// 省份編碼(參考省份編碼表)
/// </summary>
public int Province
{
get { return province; }
set { province = value; }
}
/// <summary>
/// 城市編碼(參考城市編碼表)
/// </summary>
public int City
{
get { return city; }
set { city = value; }
}
/// <summary>
/// 地址
/// </summary>
public string Location
{
get { return location; }
set { location = value; }
}
/// <summary>
/// 個人描述
/// </summary>
public string Description
{
get { return description; }
set { description = value; }
}
/// <summary>
/// 用戶博客地址
/// </summary>
public string Url
{
get { return url; }
set { url = value; }
}
/// <summary>
/// 自定義圖像
/// </summary>
public string Profile_image_url
{
get { return profile_image_url; }
set { profile_image_url = value; }
}
/// <summary>
/// 用戶個性化URL
/// </summary>
public string Domain
{
get { return domain; }
set { domain = value; }
}
/// <summary>
/// 性別,m--男,f--女,n--未知
/// </summary>
public string Gender
{
get { return gender; }
set { gender = value; }
}
/// <summary>
/// 粉絲數(shù)
/// </summary>
public int Followers_count
{
get { return followers_count; }
set { followers_count = value; }
}
/// <summary>
/// 關(guān)注數(shù)
/// </summary>
public int Friends_count
{
get { return friends_count; }
set { friends_count = value; }
}
/// <summary>
/// 微博數(shù)
/// </summary>
public int Statuses_count
{
get { return statuses_count; }
set { statuses_count = value; }
}
/// <summary>
/// 收藏數(shù)
/// </summary>
public int Favourites_count
{
get { return favourites_count; }
set { favourites_count = value; }
}
/// <summary>
/// 創(chuàng)建時間
/// </summary>
public DateTime Created_at
{
get { return created_at; }
set { created_at = value; }
}
/// <summary>
/// 是否已關(guān)注(此特性暫不支持)
/// </summary>
public bool Following
{
get { return following; }
set { following = value; }
}
/// <summary>
/// 加V標示,是否微博認證用戶
/// </summary>
public bool Verified
{
get { return verified; }
set { verified = value; }
}
#endregion
}
}
好了,經(jīng)過上面的步驟,準備工作已經(jīng)完畢,現(xiàn)在開始調(diào)用API,先看發(fā)布一條微博信息吧,雖然這篇文章(http://www.rzrgm.cn/cmt/archive/2010/05/13/1733904.html)中介紹了,但為了本文的完整我還是貼上我的代碼吧,在類庫中添加一個微博訪問類MiniBlogVisit類:
微博訪問類
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SinaMiniBlogLib
{
public class MiniBlogVisit
{
/// <summary>
/// 發(fā)布一條微博
/// </summary>
/// <param name="url">地址</param>
/// <param name="Content">微博內(nèi)容</param>
public void update(string url,string Content)
{
SendRequest send = new SendRequest();
send.SendPostRequest(url, Content);
}
}
}
調(diào)用其中的update方法就可以發(fā)布一條微博了哦。不過要注意的是這里的Content要用HttpUtility.UrlEncode進行編碼,否則會出現(xiàn)亂碼哦。
再看獲取最新更新的20條公共微博消息,也就是官方API中的第一個接口,這里返回的是XML數(shù)據(jù)或JSON數(shù)據(jù),大家可根據(jù)愛好自由選擇,我選擇的是返回XML數(shù)據(jù)。我的方法是把返回的XML數(shù)據(jù)寫入一個XML文件中,再對XML文件進行解析,代碼如下:
獲取數(shù)據(jù)代碼
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace SinaMiniBlogLib
{
public class GetNextLineData
{
#region public_timeline 獲取最新更新的20條公共微博消息
/// <summary>
/// 獲取最新更新的20條公共微博消息
/// </summary>
/// <param name="url">地址</param>
/// <param name="xmlpath">存放返回的微博信息的XML文件路徑</param>
/// <returns>IList</returns>
public IList<status> public_timeline(string url,string xmlpath)
{
SendRequest send = new SendRequest();
//發(fā)送GET請求,得到XML格式的數(shù)據(jù)
string Content=send.SendGetRequest(url);
//如果XML文件不存在就創(chuàng)建
if (!System.IO.File.Exists(xmlpath))
{
System.IO.FileStream f = System.IO.File.Create(xmlpath);
f.Close();
}
//以覆蓋的形式把數(shù)據(jù)寫入XML文件
System.IO.StreamWriter f2 = new System.IO.StreamWriter(xmlpath, false, System.Text.Encoding.GetEncoding("UTF-8"));
f2.Write(Content);
f2.Close();
f2.Dispose();
status temp;
IList<status> statusList=new List<status>();
//解析XML文件
XmlDocument myXml = new XmlDocument();
myXml.Load(xmlpath);
XmlNode users = myXml.DocumentElement;
foreach (XmlNode node in users.ChildNodes)
{
if (node.Name == "status")
{
temp = new status();
foreach (XmlNode statusnode in node.ChildNodes)
{
switch (statusnode.Name)
{
case "created_at":
temp.Created_at =ConverDateTime(statusnode.InnerText);
break;
case "id":
temp.Id = statusnode.InnerText;
break;
case "text":
temp.Text = statusnode.InnerText;
break;
case "source":
temp.Source = statusnode.InnerXml;
break;
case "favorited":
temp.Favorited =bool.Parse(statusnode.InnerText);
break;
case "truncated":
temp.Truncated = bool.Parse(statusnode.InnerText);
break;
case "in_reply_to_status_id":
temp.In_reply_to_status_id = statusnode.InnerText;
break;
case "in_reply_to_user_id":
temp.In_reply_to_user_id = statusnode.InnerText;
break;
case "in_reply_to_screen_name":
temp.In_reply_to_screen_name = statusnode.InnerText;
break;
case "user":
XmlNode usernode = statusnode.ChildNodes[0];
switch (usernode.Name)
{
case "id":
temp.User.Id = usernode.InnerText;
break;
case "screen_name":
temp.User.Screen_name = usernode.InnerText;
break;
case "name":
temp.User.Name = usernode.InnerText;
break;
case "province":
temp.User.Province =Int32.Parse(usernode.InnerText);
break;
case "city":
temp.User.City =Int32.Parse(usernode.InnerText);
break;
case "location":
temp.User.Location = usernode.InnerText;
break;
case "description":
temp.User.Description = usernode.InnerText;
break;
case "url":
temp.User.Url = usernode.InnerText;
break;
case "profile_image_url":
temp.User.Profile_image_url = usernode.InnerText;
break;
case "domain":
temp.User.Domain = usernode.InnerText;
break;
case "gender":
temp.User.Gender = usernode.InnerText;
break;
case "followers_count":
temp.User.Followers_count =Int32.Parse( usernode.InnerText);
break;
case "friends_count":
temp.User.Friends_count = Int32.Parse(usernode.InnerText);
break;
case "statuses_count":
temp.User.Statuses_count = Int32.Parse(usernode.InnerText);
break;
case "favourites_count":
temp.User.Favourites_count = Int32.Parse(usernode.InnerText);
break;
case "created_at":
temp.User.Created_at =ConverDateTime(usernode.InnerText);
break;
case "following":
temp.User.Following = bool.Parse(usernode.InnerText);
break;
case "verified":
temp.User.Verified = bool.Parse(usernode.InnerText);
break;
}
break;
}
}
statusList.Add(temp);
}
}
return statusList;
}
#endregion
#region 日期轉(zhuǎn)換
/// <summary>
/// 日期轉(zhuǎn)換
/// </summary>
/// <param name="time">新浪微博中返回的類似"Mon Oct 18 12:28:54 +0800 2010"這樣的時間</param>
/// <returns>DateTime</returns>
public DateTime ConverDateTime(string time)
{
string[] cx = time.Split(' ');
System.Globalization.DateTimeFormatInfo g = new System.Globalization.DateTimeFormatInfo();
g.LongDatePattern = "dd MMMM yyyy";
DateTime DT = DateTime.Parse(string.Format("{0} {1} {2} {3}", cx[2], cx[1], cx[5], cx[3]), g);
return DT;
}
#endregion
}
}
好了,現(xiàn)在就是調(diào)用了,調(diào)用做的比較簡單,就是一個空的Default.aspx頁面,后臺代碼如下:
調(diào)用代碼
using System.Web;
using SinaMiniBlogLib;
using System.Collections.Generic;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
//發(fā)布一條微博
MiniBlogVisit mini = new MiniBlogVisit();
//注意這里要用HttpUtility.UrlEncode進行編碼,否則會出現(xiàn)亂碼
mini.update("http://api.t.sina.com.cn/statuses/update.xml", HttpUtility.UrlEncode("測試一下XML!"));
//獲取最新更新的20條公共微博消息
GetNextLineData linedata = new GetNextLineData();
IList<status> statusList = linedata.public_timeline("http://api.t.sina.com.cn/statuses/public_timeline.xml", Server.MapPath("NextLine.xml"));
//輸出
foreach (status temp in statusList)
{
Response.Write(temp.Text+"<br/>"+temp.Created_at+" 來自"+temp.Source+"<br/><br/>");
}
}
catch (Exception ex)
{
ClientScript.RegisterStartupScript(this.GetType(), "sina", "<script type='text/javascript' language='javascript'>alert('出現(xiàn)異常,異常信息:" + ex.Message + "');</script>");
}
}
}
至此,全部代碼已經(jīng)寫完,再看看完整的解決方案吧:

運行后效果如下:

第一次調(diào)用API,也是第一次寫這么長的文章,歡迎大家多拍磚哈!!!

作者:Artwl
本文首發(fā)博客園,版權(quán)歸作者跟博客園共有。轉(zhuǎn)載必須保留本段聲明,并在頁面顯著位置給出本文鏈接,否則保留追究法律責任的權(quán)利。

浙公網(wǎng)安備 33010602011771號