上一篇:新浪微博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版)——功能实现分解介绍相关推荐

  1. 新浪微博PC客户端(DotNet WinForm C# 版,C#调用新浪微博API代码,源码下载)—— 初探 (第二部分内置链接)

    第二篇:新浪微博PC客户端(DotNet WinForm版)--功能实现分解介绍 C#源码下载 最近兴趣使然尝试了一下使用DotNet技术实现新浪微博PC客户端,几天时间,目前实现登录.微博列表.发布 ...

  2. 新浪微博PC客户端(DotNet WinForm版)—— 初探

    最近兴趣使然尝试了一下使用DotNet技术实现新浪微博PC客户端,几天时间,目前实现登录.微博列表.发布纯文本微博功能,新浪API调用基本没什么难度,在微博列表形式处理上着实让我烦躁了一阵子,Wind ...

  3. 新浪微博PC客户端,(蓝星星微博客户端)VC++

    下载地址: 华军软件站下载 非凡软件站下载 多特软件站下载 介绍: 简洁漂亮的界面,内容时实更新,不用安装air,支持屏幕截图,C++开发,速度超快,在也不用打开浏览器神马的了.屏幕截图功能是其它客户 ...

  4. 新浪微博桌面客户端 v3.0.5.35466 官方PC版

    新浪微博桌面客户端 v3.0.5.35466 官方PC版 软件大小:16.9MB 软件语言:简体中文 软件性质:常用软件 软件授权:官方版 更新时间:2014-04-29 应用平台:/WinXP/|W ...

  5. 新浪微博桌面客户端2014 v3.0.5 官方正式版

    新浪微博桌面客户端2014 v3.0.5 官方正式版 软件大小:29.2MB 软件语言:简体中文 软件性质:常用软件 软件授权:官方版 更新时间:2014-05-22 应用平台:/Win8/Win7/ ...

  6. 移动pc客户端迷你版泄露

    今天忽然发现移动pc客户端迷你版泄露了,是个绿色版,才想起来前段时间就开始报道移动要出迷你版了,马上下载使用了一下,还不错,内存占用虽然还是有点大,但是相比起那个不迷你的版本来说已经相当好了. 先上图 ...

  7. 轻笔记显示无法连接到服务器,轻笔记:支持群组的跨平台笔记应用 (1)PC客户端...

    [摘要]支持群组协作.本文为系列文章的第一篇,细致介绍了其PC客户端的功能.特点,尤其是群组协作功能. [说明]①本文是善用佳软网站的第一篇收费文章,轻笔记官方为此宣传支付了一定费用.②在与轻笔记团队 ...

  8. ios:新浪微博iphone客户端

    这算是自己做的第一个比较完整的ios的小应用程序,接触到了很多自己以前没怎么用到的东西,好像coredata,GCD,post发送请求,自定义UITableViewCell等等. 先介绍下这个小应用吧 ...

  9. pc端客户端爬虫_FIddler+Proxifer工具对windows PC客户端进行抓包

    python的大火,带动了python爬虫. 爬虫就必定绕不开抓包. 目前最常见的就是网页抓包了,可以使用chrome进行,或者配合其他抓包软件 fiddler. 小程序有些兴起是,如跳一跳之类的,也 ...

最新文章

  1. 综合布线管理系统之智能配线架的过去与将来
  2. 全球首个开放应用模型 OAM 开源 | 云原生生态周报 Vol. 23
  3. go mysql教学_Go语言之对Mysql简单操作
  4. 员外陪你读论文:DeepWalk: Online learning of Social Representations
  5. uva 10271——Chopsticks
  6. Discord 公司如何使用 Cassandra 存储上亿条线上数据
  7. Java的一些基础知识深入
  8. Atitit 如何工作积极的心态积极起来
  9. 新萝卜家园 GhostXP_SP3 五一纪念版
  10. java学习电子书_Java学习指南(第4版)(上册) 中文完整pdf扫描版[179MB]
  11. 【全开源功放】意法微电子的经典芯片,TDA7294!
  12. 【求助】如何在移动固态硬盘上装一个完美的移动系统
  13. (转)一位资深程序员大牛给予Java初学者的学习路线建议
  14. C# 操作Word页眉页脚——奇偶页/首页不同、不连续设置页码、复制页眉页脚、锁定页眉页脚、删除页眉...
  15. 看最强大脑的数字华容道,尝试理解与总结
  16. 集美大学第七届天梯赛校选题解
  17. C#,数值计算,求解微分方程的吉尔(Gear)四阶方法与源代码
  18. 排查Java宕机,weblogic宕机问题排查
  19. 机械键盘caps键和ctrl键颠倒,解决办法
  20. Android底部弹出选择框PickerView的使用

热门文章

  1. 乓乓响再度冲刺港股:来自临时及应急服务客户毛利率达70%
  2. 电大计算机专业毕业自我鉴定,广播电视大学毕业自我鉴定3篇
  3. 中科院计算机学院考研真题,2021年862计算机学科中国科学院大学考研真题及详解...
  4. sop8语音芯片选型,九齐硕呈等等比较,看完此篇就足够了
  5. 搜狐新浪ip库查询接口的使用
  6. QT项目之键盘控制光标移动
  7. 电脑误删的文件怎么恢复?分享90%的人都会的这2招
  8. Python4班平均成绩统计_重磅!长春12所热门高中高考成绩全部“亮相”!你看好谁?!...
  9. 网易互娱2017实习生招聘在线笔试第一场-题目3
  10. java计算机毕业设计临大新生入学指导系统源代码+数据库+系统+lw文档