新浪微博PC客户端(DotNet WinForm版)——功能实现分解介绍
上一篇:新浪微博PC客戶端(DotNet WinForm版)—— 初探
?
說明一下:只是興趣,并不是想發布為一個軟件,說實在的,如果要作為一個軟件發布,要做的工作還有很多。?
?
新浪微博API地址:http://open.t.sina.com.cn/wiki/index.php/API%E6%96%87%E6%A1%A3?retcode=0。
目前提供的SDK:
?
- 1?Adobe Air
- 2?Flash SDK
- 3?PHP
- 4?C++
- 5?C#
- 6?Java SDK
- 7?Python SDK
- 8?Javascript SDK(JSSDK)
- 9?iOS SDK
- 10?OAuth Library
其它的不清楚,C#的還不完善,而且不是官方的。
?
當前已實現的功能:
?1、HTTP普通鑒權(Basic Authentication)的身份驗證方式,說白了就是每次訪問API都要發送帳號和密碼,當然是不安全的,但是相比OAuth驗證方式門檻要低的多。要使用OAuth驗證方式可以去看下SDK。
===》account/verify_credentials?驗證當前用戶身份是否合法?
?
OAuth是一種國際通用的授權方式,它的特點是不需要用戶在第三方應用輸入用戶名及密碼。OAuth的技術說明可參看官方網站 http://oauth.net。學習和研究OAuth的意義不僅僅在于新浪圍脖,而是對以后開發類似的項目非常有意義和價值(如果你還不知道OAuth授權方式)。
?
驗證通過則返回用戶的個人信息,參照下面的API字段說明。
API字段說明
- status?微博信息內容
- user?用戶資料信息
- comment?評論信息描述
- direct_message?私信信息
- 省份城市編碼表
?
上一篇說了,API返回的結果格式有兩種:XML和JSON,在調用API的時候可以指定。
這里我指定的是XML格式,實現代碼如下:
登錄窗體:FrmLogin.cs,可以看上一篇的截圖。?
(1)把申請AppKey和AppSecret寫到app.config?
<? xml?version="1.0"?encoding="utf-8"? ?>< configuration >
?? < appSettings >
???? < add? key ="AppKey" ?value ="3476523072" />
???? < add? key ="AppSecret" ?value ="3c909770efa6865fd5843a564545826d" />
?? </ appSettings >
</ configuration >
?
要申請AppKey,需要登錄新浪圍脖,然后在這個地址創建應用并生成:?http://open.t.sina.com.cn/apps/new。
(2)創建了一個靜態類,保存用戶信息?
代碼 using ?System;using ?System.Collections.Generic;
using ?System.Linq;
using ?System.Text;
using ?System.Runtime.Serialization;
namespace ?MBClient.Entities
{
???? /// ? <summary>
???? /// ?微博帳號資料
???? /// ? </summary>
???? internal ? class ?UserInfo
????{
???????? internal ?UserInfo(){?}
???????? internal ? static ? string ?UserName?{? get ;? set ;?}
???????? internal ? static ? string ?Password?{? get ;? set ;?}
???????? internal ? static ? string ?UserNamePassword?{? get ;? set ;?}
???????? internal ? static ? int ?ID?{? get ;? set ;?}
???????? internal ? static ? string ?ScreenName?{? get ;? set ;?}
???????? internal ? static ? string ?Name?{? get ;? set ;?}
???????? internal ? static ? int ?Province?{? get ;? set ;?}
???????? internal ? static ? int ?City?{? get ;? set ;?}
???????? internal ? static ? string ?Location?{? get ;? set ;?}
???????? internal ? static ? string ?Description?{? get ;? set ;?}
???????? internal ? static ? string ?Url?{? get ;? set ;?}
???????? internal ? static ? string ?ProfileImageUrl?{? get ;? set ;?}
???????? internal ? static ? string ?Domain?{? get ;? set ;?}
???????? internal ? static ? string ?Gender?{? get ;? set ;?}
???????? /// ? <summary>
???????? /// ?粉絲數
???????? /// ? </summary>
???????? internal ? static ? int ?FollowersCount?{? get ;? set ;?}
???????? /// ? <summary>
???????? /// ?關注數
???????? /// ? </summary>
???????? internal ? static ? int ?FriendsCount?{? get ;? set ;?}
???????? /// ? <summary>
???????? /// ?微博數
???????? /// ? </summary>
???????? internal ? static ? int ?StatusesCount?{? get ;? set ;?}
???????? internal ? static ? int ?FavouritesCount?{? get ;? set ;?}
???????? /// ? <summary>
???????? /// ?微博帳號日期
???????? /// ? </summary>
???????? internal ? static ? string ?CreatedAt?{? get ;? set ;?}
???????? internal ? static ? bool ?Following?{? get ;? set ;?}
???????? internal ? static ? bool ?Verified?{? get ;? set ;?}
???????? internal ? static ? bool ?AllowAllActMsg?{? get ;? set ;?}
???????? internal ? static ? bool ?GeoEnabled?{? get ;? set ;?}
????}
}
?
??
(3)調用API?
代碼 using ?System;using ?System.Collections.Generic;
using ?System.Text;
using ?System.IO;
using ?System.Net;
using ?MBClient.Entities;
using ?System.Runtime.Serialization.Json;
using ?System.Data;
using ?System.Drawing;
using ?MBClient.Class;
namespace ?MBClient.API
{
???? internal ? class ?ReadDataBySinaAPI
????{
???????? internal ?ReadDataBySinaAPI()?{?}
???????? /// ? <summary>
???????? /// ?根據用戶登錄信息登錄并讀取用戶信息到DataSet
???????? /// ? </summary>
???????? /// ? <param?name="url"> API?URL?(XML?Format) http://api.t.sina.com.cn/account/verify_credentials.xml?source=AppKey </param>
???? /// ? <param?name="httpRequestMethod)"> HTTP請求方式:GET或POST </param>
???????? /// ? <returns></returns>
???????? internal ? static ?DataSet?ReadXMLDataToDataSet( string ?url,? string ?httpRequestMethod)
????????{
???????????? try
????????????{
????????????????WebResponse?wr? = ?BasicAuthorizationRequest(url,?httpRequestMethod).GetResponse();
????????????????DataSet?ds? = ? new ?DataSet();
????????????????Stream?receieveStream? = ?wr.GetResponseStream();
????????????????StreamReader?reader? = ? new ?StreamReader(receieveStream,?Encoding.UTF8);
????????????????ds.ReadXml(reader);
????????????????reader.Close();
????????????????receieveStream.Close();
????????????????wr.Close();
???????????????? return ?ds;
????????????}
???????????? catch ?(Exception?e)
????????????{
???????????????? return ? null ;
????????????}
????????}
???????? /// ? <summary>
???????? /// ?HTTP普通驗證(Basic?Authentication)方式
???????? /// ? </summary>
???????? /// ? <param?name="url"> API?URL </param>
???????? /// ? <param?name="httpRequestMethod)"> HTTP請求方式:GET或POST </param>
???????? /// ? <returns></returns>
???????? private ? static ?WebRequest?BasicAuthorizationRequest( string ?url,? string ?httpRequestMethod)
????????{
????????????CredentialCache?mycache? = ? new ?CredentialCache();
????????????mycache.Add( new ?Uri(url),? " Basic " ,? new ?NetworkCredential(UserInfo.UserName,?UserInfo.Password));
????????????WebRequest?myReq? = ?WebRequest.Create(url);
????????????myReq.Credentials? = ?mycache;
????????????myReq.Headers.Add( " Authorization " ,? " Basic? " ? + ?Convert.ToBase64String( new ?ASCIIEncoding().GetBytes(UserInfo.UserNamePassword)));
????????????myReq.Method? = ?httpRequestMethod;
???????????? return ?myReq;
????????}
????}
}
?
?
?我這里直接用DataSet讀取XML了,當然也可以將XML數據反序列化,后面會看到,我將返回的JSON格式的圍脖信息進行了反序列化。
(4)登錄窗體代碼
代碼 using ?System;using ?System.Data;
using ?System.Windows.Forms;
using ?MBClient.Entities;
using ?MBClient.API;
using ?MBClient.Class;
using ?Sunisoft.IrisSkin;
using ?System.Threading;
namespace ?MBClient
{
???? public ? partial ? class ?FrmLogin?:?Form
????{
???????? string ?ErrorMsg? = ? null ;
???????? public ?FrmLogin()
????????{
????????????InitializeComponent();
???????????? this .skinEngine.SkinFile? = ? @" skin\msn.ssk " ;
???????????? this .Text? = ? " 登錄 " ? + ?Properties.Resources.SoftName;
????????}
???????? private ? void ?FrmLogin_Load( object ?sender,?EventArgs?e)
????????{
???????????? // this.TransparencyKey?=?this.BackColor;
???????????? // 各線程之間沒有互相爭搶控件資源的情況,設置允許跨線程訪問
????????????CheckForIllegalCrossThreadCalls? = ? false ;
????????????cBoxAccountSina.Select();
????????????InitBackGroundWorker();
????????}
???????? private ? void ?InitBackGroundWorker()
????????{
????????????backWorker.DoWork? += ? new ?System.ComponentModel.DoWorkEventHandler(backWorker_DoWork);
????????????backWorker.ProgressChanged? += ? new ?System.ComponentModel.ProgressChangedEventHandler(backWorker_ProgressChanged);
????????????backWorker.RunWorkerCompleted? += ? new ?System.ComponentModel.RunWorkerCompletedEventHandler(backWorker_RunWorkerCompleted);
????????}
???????? void ?backWorker_ProgressChanged( object ?sender,?System.ComponentModel.ProgressChangedEventArgs?e)
????????{
???????????? // throw?new?NotImplementedException();
????????}
???????? void ?backWorker_RunWorkerCompleted( object ?sender,?System.ComponentModel.RunWorkerCompletedEventArgs?e)
????????{
???????????? if ?(ErrorMsg? == ? null )
????????????{
????????????????System.Threading.Thread.Sleep( 200 );
????????????????FrmMain?main? = ? new ?FrmMain();
???????????????? this .Hide();
????????????????main.Show();
????????????}
???????????? else
????????????{
????????????????tabControl.Visible? = ? true ;
????????????????MessageBox.Show(ErrorMsg,? " 登錄失敗 " ,?MessageBoxButtons.OK,
????????????????????MessageBoxIcon.Exclamation);
????????????}
????????}
???????? void ?backWorker_DoWork( object ?sender,?System.ComponentModel.DoWorkEventArgs?e)
????????{
???????????? try
????????????{
????????????????ErrorMsg? = ? null ;
????????????????UserInfo.UserName? = ?cBoxAccountSina.Text.Trim();?;
????????????????UserInfo.Password? = ?txtPwdSina.Text.Trim();
????????????????UserInfo.UserNamePassword? = ?UserInfo.UserName? + ? " : " ? + ?UserInfo.Password;
???????????????? // source參數為申請的新浪微博App?Key
???????????????? string ?url? = ?Function.ACCOUNTVERIFY? + ? " ?source= " ? + ?Function.APPKEY;
????????????????DataSet?ds? = ?ReadDataBySinaAPI.ReadXMLDataToDataSet(url,? " GET " );
????????????????DataRow?dr? = ?ds.Tables[ 0 ].Rows[ 0 ];
???????????????? #region ? // 將用戶信息保存到UserInfo
????????????????UserInfo.AllowAllActMsg? = ? bool .Parse(dr[ " allow_all_act_msg " ].ToString());
????????????????UserInfo.City? = ? int .Parse(dr[ " city " ].ToString());
????????????????UserInfo.CreatedAt? = ?dr[ " created_at " ].ToString();
????????????????UserInfo.Description? = ?dr[ " description " ].ToString();
????????????????UserInfo.Domain? = ?dr[ " domain " ].ToString();
????????????????UserInfo.FavouritesCount? = ? int .Parse(dr[ " favourites_count " ].ToString());
????????????????UserInfo.FollowersCount? = ? int .Parse(dr[ " followers_count " ].ToString());
????????????????UserInfo.Following? = ? bool .Parse(dr[ " following " ].ToString());
????????????????UserInfo.FriendsCount? = ? int .Parse(dr[ " friends_count " ].ToString());
????????????????UserInfo.Gender? = ?dr[ " gender " ].ToString();
????????????????UserInfo.GeoEnabled? = ? bool .Parse(dr[ " geo_enabled " ].ToString());
????????????????UserInfo.ID? = ? int .Parse(dr[ " ID " ].ToString());
????????????????UserInfo.Location? = ?dr[ " location " ].ToString();
????????????????UserInfo.Name? = ?dr[ " name " ].ToString();
????????????????UserInfo.ProfileImageUrl? = ?dr[ " profile_image_url " ].ToString();
????????????????UserInfo.Province? = ? int .Parse(dr[ " province " ].ToString());
????????????????UserInfo.ScreenName? = ?dr[ " screen_name " ].ToString();
????????????????UserInfo.StatusesCount? = ? int .Parse(dr[ " statuses_count " ].ToString());
????????????????UserInfo.Url? = ?dr[ " url " ].ToString();
????????????????UserInfo.Verified? = ? bool .Parse(dr[ " verified " ].ToString());
???????????????? #endregion
????????????}
???????????? catch ?(Exception?ex)
????????????{
????????????????ErrorMsg? = ?ex.Message;
????????????}
????????}
???????? private ? void ?FrmLogin_FormClosing( object ?sender,?FormClosingEventArgs?e)
????????{
????????????Application.ExitThread();
????????}
???????? private ? void ?btnLoginSina_Click( object ?sender,?EventArgs?e)
????????{
????????????tabControl.Visible? = ? false ;
????????????backWorker.RunWorkerAsync();
????????}
???????? private ? void ?btnRegSina_Click( object ?sender,?EventArgs?e)
????????{
????????????System.Diagnostics.Process.Start( " http://t.sina.com.cn/reg.php?ps=u3&lang=zh " );
????????}
????}
}
?
?
關于登錄窗體的代碼,說兩點:
(1)使用皮膚
在你的Windows系統盤搜索IrisSkin2.dll
找到后添加到工具箱,右擊工具箱——選擇項——選擇這個dll
然后將SkinEngine控件拖到窗體上,在代碼中按照如下方式寫:
this .skinEngine.SkinFile? = ? @" skin\msn.ssk " ;?
這個ssk文件我使用了網上的資源,你也可以到網上去搜,可以下載到有20種左右的皮膚,有了皮膚文件,要實現換膚功能就非常簡單了。你也可以使用皮膚工具生成皮膚,如:skin++。?
?
(2)使用BackgroundWorker異步加載 :關于BackgroundWorker,MSDN說的很清楚了,這里不再贅述,http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(v=vs.80).aspx。
?
2、獲取當前登錄用戶及其所關注用戶的最新微博消息,并分頁顯示,這兒是我代碼最多的地方,主要是由于所有顯示的控件都動態加載的緣故。
今天看到新浪圍脖API更新了(近一個周都沒看),之前是只能傳頁碼,默認每頁返回20條數據;現在是可以傳頁碼和返回數據的條數。
===》statuses/friends_timeline?獲取當前登錄用戶及其所關注用戶的最新微博消息 (別名: statuses/home_timeline)
?
這里在第一次加載和翻頁時也使用BackgroundWorker。具體代碼不貼出來了,代碼太長,后面提供下載,供參考。
?
具體實現簡單說一下:
根據調用接口返回的JSON數據格式化為泛型對象集合,然后遍歷集合在Panel中動態添加控件顯示數據,主要一點是要計算好控件的位置。
(1)圍脖類??
代碼 using ?System;using ?System.Collections.Generic;
using ?System.Linq;
using ?System.Text;
using ?System.Runtime.Serialization;
namespace ?MBClient.Entities
{
????[DataContract]
???? internal ? class ?Status
????{
????????[DataMember]
???????? internal ? string ?created_at?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?id?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?text?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?source?{? get ;? set ;?}
????????[DataMember]
???????? internal ? bool ?favorited?{? get ;? set ;?}
????????[DataMember]
???????? internal ? bool ?truncated?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?geo?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?in_reply_to_status_id?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?in_reply_to_user_id?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?in_reply_to_screen_name?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?thumbnail_pic?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?bmiddle_pic?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?original_pic?{? get ;? set ;?}
????????[DataMember]
???????? internal ?PostUser?user?{? get ;? set ;?}
????????[DataMember]
???????? internal ?RetweetedStatus?retweeted_status?{? get ;? set ;?}
????}
}
?
??
(2)用戶類??
代碼 using ?System;using ?System.Collections.Generic;
using ?System.Linq;
using ?System.Text;
using ?System.Runtime.Serialization;
namespace ?MBClient.Entities
{
????[DataContract]
???? internal ? class ?PostUser
????{
????????[DataMember]
???????? internal ? string ?id?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?screen_name?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?name?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?province?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?city?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?location?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?description?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?url?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?profile_image_url?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?domain?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?gender?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?followers_count?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?friends_count?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?statuses_count?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?favourites_count?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?created_at?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?following?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?verified?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?allow_all_act_msg?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?geo_enabled?{? get ;? set ;?}
????}
}
?
?
(3)轉發的圍脖類?
代碼 using ?System;using ?System.Collections.Generic;
using ?System.Linq;
using ?System.Text;
using ?System.Runtime.Serialization;
namespace ?MBClient.Entities
{
????[DataContract]
???? internal ? class ?RetweetedStatus
????{
????????[DataMember]
???????? internal ? string ?created_at?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?id?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?text?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?source?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?favorited?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?truncated?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?geo?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?in_reply_to_status_id?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?in_reply_to_user_id?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?in_reply_to_screen_name?{? get ;? set ;?}
????[DataMember]
???????? internal ? string ?thumbnail_pic?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?bmiddle_pic?{? get ;? set ;?}
????????[DataMember]
???????? internal ? string ?original_pic?{? get ;? set ;?}
????????[DataMember]
???????? internal ?PostUser?user?{? get ;? set ;?}
????}
}
?
??
(4)根據URL輸出頭像或圖片?
?? ? ? ? /// ? <summary>???????? /// ?獲取并輸出圖片
???????? /// ? </summary>
???????? /// ? <param?name="imgUrl"> 圖片URL地址 </param>
???????? /// ? <returns></returns>
???????? internal ? static ?Image?GetAvatarImage( string ?imgUrl)
????????{
???????????? try
????????????{
????????????????Uri?myUri? = ? new ?Uri(imgUrl);
????????????????WebRequest?webRequest? = ?WebRequest.Create(myUri);
????????????????WebResponse?webResponse? = ?webRequest.GetResponse();
????????????????Bitmap?myImage? = ? new ?Bitmap(webResponse.GetResponseStream());
???????????????? return ?(Image)myImage;
????????????}
???????????? catch ?(Exception?e)
????????????{
???????????????? return ? null ;
????????????}
????????}
???
可以去看一下上一篇我貼出的XML數據,基本就清楚了?
?
(5)讀取微博信息并反序列化 ??
代碼 ???? /// ? <summary>???????? /// ?以JSON格式字符串返回用戶所有關注用戶最新n條微博信息。和用戶“我的首頁”返回內容相同。
???????? /// ? http://open.t.sina.com.cn/wiki/index.php/Statuses/friends_timeline
???????? /// ? </summary>
???????? /// ? <param?name="url"> API?URL?(JSON?Format)? http://api.t.sina.com.cn/statuses/friends_timeline.json?source=AppKey </param>
???????? /// ? <param?name="httpRequestMethod"> HTTP請求方式 </param>
???????? /// ? <returns></returns>
???????? internal ? static ? string ?ReadJsonDataToString( string ?url,? string ?httpRequestMethod)
????????{
???????????? try
????????????{
????????????????WebResponse?wr? = ?BasicAuthorizationRequest(url,?httpRequestMethod).GetResponse();
???????????????? string ?content? = ? null ;
????????????????Stream?receieveStream? = ?wr.GetResponseStream();
????????????????StreamReader?reader? = ? new ?StreamReader(receieveStream,?Encoding.UTF8);
????????????????content? = ?reader.ReadToEnd();
????????????????reader.Close();
????????????????receieveStream.Close();
????????????????wr.Close();
???????????????? return ?content;
????????????}
???????????? catch ?(Exception?e)
????????????{
???????????????? return ? null ;
????????????}
????????}
???????? /// ? <summary>
???????? /// ?將JSON格式字符串反序列化為Status集合對象
???????? /// ? </summary>
???????? /// ? <param?name="url"> 同ReadJsonDataToString() </param>
???????? /// ? <param?name="httpRequestMethod"> HTTP請求方式 </param>
???????? /// ? <returns></returns>
???????? internal ? static ?List < Status > ?DeserializeJsonToListObject( string ?url,? string ?httpRequestMethod)
????????{
???????????? try
????????????{
????????????????List < Status > ?listObj;
????????????????MemoryStream?stream? = ? new ?MemoryStream();
????????????????DataContractJsonSerializer?ser? = ? new ?DataContractJsonSerializer( typeof (List < Status > ));
????????????????StreamWriter?wr? = ? new ?StreamWriter(stream);
????????????????wr.Write(ReadJsonDataToString(url,?httpRequestMethod));
????????????????wr.Flush();
????????????????stream.Position? = ? 0 ;
????????????????Object?obj? = ?ser.ReadObject(stream);
????????????????listObj? = ?(List < Status > )obj;
????????????????wr.Close();
????????????????stream.Close();
???????????????? return ?listObj;
????????????}
???????????? catch ?(Exception?e)
????????????{
???????????????? return ? null ;
????????????}
????????}
?
?
3、發表圍脖
下面的方法還是寫在ReadDataBySinaAPI這個類里。?
發表圍脖分為兩種情況:
(1)純文本 ===》statuses/update?發布一條微博信息??
代碼 ??????? /// ? <summary>???????? /// ?發表一條微博
???????? /// ? </summary>
???????? /// ? <param?name="url"> API?URL? http://api.t.sina.com.cn/statuses/update.json ? </param>
???????? /// ? <param?name="data"> AppKey和微博內容??"source=123456&status="?+?微博內容;? </param>
???????? /// ? <param?name="httpRequestMethod"> HTTP請求方式 </param>
???????? /// ? <returns></returns>
???????? internal ? static ? bool ?PostBlog( string ?url,? string ?data,? string ?httpRequestMethod)
????????{
???????????? try
????????????{
????????????????HttpWebRequest?httpRequest? = ?BasicAuthorizationRequest(url,?httpRequestMethod)? as ?HttpWebRequest;
????????????????httpRequest.ContentType? = ? " application/x-www-form-urlencoded " ;
????????????????Encoding?encoding? = ?Encoding.UTF8; // System.Text.Encoding.ASCII
???????????????? byte []?bytesToPost? = ?encoding.GetBytes(data); // System.Web.HttpUtility.UrlEncode(data)
????????????????httpRequest.ContentLength? = ?bytesToPost.Length;
????????????????Stream?requestStream? = ?httpRequest.GetRequestStream();
????????????????requestStream.Write(bytesToPost,? 0 ,?bytesToPost.Length);
????????????????requestStream.Close();
???????????????? return ? true ;
????????????}
???????????? catch
????????????{
???????????????? return ? false ;
????????????}
????????}
?
????
(2)帶圖片 ===》statuses/upload?上傳圖片并發布一條微博信息??
代碼 ???????? /// ? <summary>???????? /// ?發布帶圖片的微博
???????? /// ?ref: http://sarlmolapple.is-programmer.com/posts/22435.html
???????? /// ? </summary>
???????? /// ? <param?name="url"> 微博API </param>
???????? /// ? <param?name="data"> 包含微博內容和圖片的集合 </param>
???????? /// ? <param?name="httpRequestMethod"> HTTP請求方式 </param>
???????? /// ? <returns></returns>
???????? internal ? static ? bool ?PostBlogWithPic( string ?url,?List < string > ?data,? string ?httpRequestMethod)
????????{
???????????? try
????????????{
????????????????HttpWebRequest?httpRequest? = ?BasicAuthorizationRequest(url,?httpRequestMethod)? as ?HttpWebRequest;
????????????????httpRequest.PreAuthenticate? = ? true ;
????????????????httpRequest.AllowWriteStreamBuffering? = ? true ;
???????????????? string ?boundary? = ?Guid.NewGuid().ToString();
????????????????httpRequest.ContentType? = ? string .Format( " multipart/form-data;?boundary={0} " ,?boundary);
???????????????? string ?header? = ? string .Format( " --{0} " ,?boundary);
???????????????? string ?footer? = ? string .Format( " --{0}-- " ,?boundary);
????????????????StringBuilder?contents? = ? new ?StringBuilder();
????????????????contents.AppendLine(header);
????????????????contents.AppendLine(String.Format( " Content-Disposition:?form-data;?name=\ " { 0 }\ "" ,? " status " ));
????????????????contents.AppendLine( " Content-Type:?text/plain;?charset=utf-8 " ); // US-ASCII
????????????????contents.AppendLine( " Content-Transfer-Encoding:?8bit " );
????????????????contents.AppendLine();
???????????????? // 微博文字
????????????????contents.AppendLine(data[ 0 ]);
????????????????contents.AppendLine(header);
????????????????contents.AppendLine( string .Format( " Content-Disposition:?form-data;?name=\ " { 0 }\ "" ,? " source " ));
????????????????contents.AppendLine( " Content-Type:?text/plain;?charset=utf-8 " ); // US-ASCII
????????????????contents.AppendLine( " Content-Transfer-Encoding:?8bit " );
????????????????contents.AppendLine();
????????????????contents.AppendLine(Function.APPKEY);
???????????????? byte []?bytesToPost? = ?Encoding.UTF8.GetBytes(contents.ToString());
???????????????? // 微博圖片
????????????????contents? = ? null ;
????????????????contents? = ? new ?StringBuilder();
????????????????contents.AppendLine(header);
???????????????? string ?fileHeader? = ? string .Format( " Content-Disposition:?form-data;?name=\ " { 0 }\ " ;?filename=\ " { 1 }\ "" ,? " pic " ,?boundary);
???????????????? string ?fileData? = ?Encoding.GetEncoding( " iso-8859-1 " ).GetString(File.ReadAllBytes(@data[ 1 ]));
????????????????contents.AppendLine(fileHeader);
????????????????contents.AppendLine( " Content-Type:?application/octet-stream;?charset=utf-8 " );
????????????????contents.AppendLine( " Content-Transfer-Encoding:?binary " );
????????????????contents.AppendLine();
????????????????contents.AppendLine(fileData);
????????????????contents.AppendLine(footer);
???????????????? byte []?bytesToPost2? = ?Encoding.GetEncoding( " iso-8859-1 " ).GetBytes(contents.ToString());
????????????????httpRequest.ContentLength? = ?bytesToPost.Length? + ?bytesToPost2.Length;
????????????????Stream?requestStream? = ?httpRequest.GetRequestStream();
????????????????requestStream.Write(bytesToPost,? 0 ,?bytesToPost.Length);
????????????????requestStream.Write(bytesToPost2,? 0 ,?bytesToPost2.Length);
????????????????requestStream.Close();
???????????????? return ? true ;
????????????}
???????????? catch (Exception?e)
????????????{
???????????????? return ? false ;
????????????}
????????}
?
這里要注意的一點是iso-8859-1這種編碼方式不支持中文,所以,把圖片內容和非圖片內容分開處理了。
?
(3)驗證輸入字數不能超過140字符?
?? ? ?? // 計算字符串長度,中文及全角算1,其它算0.5???????? internal ? static ? int ?GetStringLength( string ?text)
????????{
???????????? int ?Len? = ? 0 ;
???????????? // 記錄非中文、非全角字符為0.5個長度
???????????? float ?charLen? = ? 0 ;
???????????? char []?chars? = ?text.ToCharArray();
???????????? for ?( int ?i? = ? 0 ;?i? < ?chars.Length;?i ++ )
????????????{
???????????????? int ?charLength? = ?Encoding.UTF8.GetByteCount(chars[i].ToString());
???????????????? if ?(charLength? == ? 3 )
????????????????{
????????????????????Len ++ ;
????????????????}
???????????????? else
????????????????{
???????????????????? if ?(charLen? == ? 0.5 )
????????????????????{
????????????????????????charLen? = ? 0 ;
????????????????????}
???????????????????? else
????????????????????{
????????????????????????charLen? = ? 0.5f ;
????????????????????????Len ++ ;
????????????????????}
????????????????}
????????????}
???????????? return ?Len;
????????}
?
??
4、轉發圍脖 ===》statuses/repost?轉發一條微博信息
用的這個方法PostBlog(),HTTP請求方式為POST。?
?
5、評論圍脖 ===》statuses/comment?對一條微博信息進行評論
用的這個方法PostBlog(),HTTP請求方式為POST。?
?
6、收藏圍脖 ===》favorites/create?添加收藏
用的這個方法ReadXMLDataToDataSet(),HTTP請求方式為POST。?
?
7、降低工作內存?
?? ? ? ? /// ? <summary>???????? /// ?設置工作內存,降低內存占用
???????? /// ? </summary>
???????? /// ? <param?name="maxWorkingSet"> 內存中允許的進程的最大工作集大小(以字節為單位) </param>
???????? public ? static ? void ?SetWorkingSet( int ?maxWorkingSet)
????????{
????????????System.Diagnostics.Process.GetCurrentProcess().MaxWorkingSet? = ?(IntPtr)maxWorkingSet;
????????}
?
HTTP請求方式,API中有說明,所以上面沒有一一指出。?
?
可參考資料:
CredentialCache:http://msdn.microsoft.com/zh-cn/library/system.net.credentialcache(v=VS.90).aspx
WebRequest:http://msdn.microsoft.com/zh-cn/library/system.net.webrequest(v=VS.90).aspx
NetworkCredential:http://msdn.microsoft.com/zh-cn/library/system.net.networkcredential(v=VS.90).aspx
Basic Access Authentication:http://en.wikipedia.org/wiki/Basic_access_authentication;Basic:基本;digest:簡要?
?
枝枝節節的還有不少內容,不一一說了,稍后我提供源碼,有興趣的可以看下,一起討論。
?
最后,圍脖=微博,呵呵。?
?
先提供編譯后的,供測試:/Files/Ferry/MBPCClient/微博客戶端.rar
?
C#源碼下載?
轉載于:https://www.cnblogs.com/Ferry/archive/2010/12/11/1902715.html
總結
以上是生活随笔為你收集整理的新浪微博PC客户端(DotNet WinForm版)——功能实现分解介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 扫雷——关于展开空格的算法
- 下一篇: oracle 与plc通信,cim系统(