我们只知道通讯的请求和结果,逻辑结构并不是完全明白。
在这里我想将每条动弹的信息原封不动的显示在界面中。
所以需要控件做一些扩展,来将HTML标记转换为视图。
WPF可以很完美的实现自定义控件,开发者的Idea可以很简洁的被呈现,这是我选择WPF的原因。
接下来将构筑控件,这里利用到了WebBrowser,HtmlAgilityPack
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Net;
using System.IO;
namespace OCMove
{
public enum HttpMethodType
{
[Description("GET")]
GET = 0,
[Description("POST")]
POST = 1,
[Description("PUT")]
PUT = 2,
}
public class HttpObject
{
public virtual string Send(HttpMethodType method,
string hostUrl,
string queryString,
WebHeaderCollection header,
byte[] requestBody,
IWebProxy proxy,
CookieContainer cc,
int timeout,
AsyncCallback callback)
{
string methodType = "GET";
string url = hostUrl;
string referer = "";
Uri uriRequest = null;
bool bkeeplive = true;
string useragent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";
string contenttype = "application/x-www-form-urlencoded";
#region Method
switch (method)
{
case HttpMethodType.POST:
{
methodType = "POST";
break;
}
case HttpMethodType.PUT:
{
methodType = "PUT";
break;
}
case HttpMethodType.GET:
default:
{
methodType = "GET";
break;
}
}
#endregion //Method
#region URL
if (!string.IsNullOrEmpty(queryString))
{
url = string.Format("{0}?{1}", hostUrl, queryString);
}
uriRequest = new Uri(url);
if (uriRequest.ToString().ToLower().StartsWith("https"))
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
}
System.Net.ServicePointManager.Expect100Continue = false;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriRequest);
#endregion //URL
#region Headers
if (header != null)
{
referer = header[HttpRequestHeader.Referer] as string;
bkeeplive = Convert.ToBoolean(header[HttpRequestHeader.KeepAlive]);
useragent = header[HttpRequestHeader.UserAgent] as string;
contenttype = header[HttpRequestHeader.ContentType] as string;
//request.Headers = header;
}
#endregion //Headers
#region Settings
if (!string.IsNullOrEmpty(referer))
{
request.Referer = referer;
}
request.Proxy = proxy == null ? HttpWebRequest.DefaultWebProxy : proxy;
request.CookieContainer = cc;
request.KeepAlive = bkeeplive==null ? true : bkeeplive;
request.UserAgent = string.IsNullOrEmpty(useragent) ? "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)" : useragent;
request.Timeout = timeout;
request.Method = methodType;
#endregion //Settings
if (method == HttpMethodType.POST ||
method == HttpMethodType.PUT)
{
request.ContentType = string.IsNullOrEmpty(contenttype) ? "application/x-www-form-urlencoded" : contenttype;
request.ContentLength = requestBody.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(requestBody, 0, requestBody.Length);
newStream.Close();
}
try
{
if (callback == null)
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Encoding encoding = !string.IsNullOrEmpty(response.ContentEncoding) ? Encoding.GetEncoding(response.ContentEncoding) : Encoding.UTF8;
Stream stream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(stream, encoding))
{
return reader.ReadToEnd();
}
}
else
{//使用异步方式
request.BeginGetResponse(callback, request);
}
return HttpStatusCode.OK.ToString();
}
catch (Exception ex)
{
return ex.Message;
}
}
//https
private static bool CheckValidationResult(object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors errors)
{ // Always accept
return true;
}
}
public class HttpAction : HttpObject
{
#region Constructors
public HttpAction()
{
}
public HttpAction(HttpMethodType mode,string url)
: this(mode, url, null, null)
{
}
public HttpAction(HttpMethodType mode, string url,string bodydata)
: this(mode, url, null, bodydata)
{
}
public HttpAction(HttpMethodType mode, string url, WebHeaderCollection headers)
:this(mode,url,headers,null)
{
}
public HttpAction(HttpMethodType mode, string url,WebHeaderCollection headers ,string bodydata)
{
this.ActionMode = mode;
this.Url = url;
if (headers != null)
{
this.RequestHeaders = headers;
}
if (!string.IsNullOrEmpty(bodydata))
{
this.BodyData = bodydata;
}
this.Encoding = Encoding.UTF8;
RequestHeaders = new WebHeaderCollection();
}
#endregion
private CookieContainer m_Cookies = new CookieContainer();
private int m_TimeOut = 3000;
private string m_ContentType = "application/x-www-form-urlencoded";
private WebHeaderCollection m_ResponseHeaders = new WebHeaderCollection();
public HttpMethodType ActionMode{get;set;}
public string Url { get; set; }
public string QueryText { get; set; }
public WebHeaderCollection RequestHeaders { get; set; }
public string BodyData { get; set; }
public Encoding Encoding { get; set; }
/// <summary>
/// 设置连接超时时间(ms)
/// </summary>
public int TimeOut
{
set { m_TimeOut = value; }
get { return m_TimeOut; }
}
/// <summary>
/// 设置/获取CookieContainer
/// </summary>
public CookieContainer Cookies
{
get { return m_Cookies; }
set { m_Cookies = value; }
}
/// <summary>
/// 设置请求的内容类型
/// </summary>
public string ContentType
{
set { m_ContentType = value; }
get {return m_ContentType;}
}
/// <summary>
/// 获取或者设置请求返回的HTTP标头
/// </summary>
public WebHeaderCollection ResponseHeaders
{
get { return m_ResponseHeaders; }
}
/// <summary>
/// 回调事件(声明了回调函数则使用异步请求)
/// </summary>
public event EventHandler<ResponseComplatedArgs> ResponseComplate;
private void RespCallback(IAsyncResult result)
{
string responseText ="";
HttpStatusCode code = HttpStatusCode.Unused;
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
this.m_ResponseHeaders = response.Headers;
code = response.StatusCode;
Encoding encoding = !string.IsNullOrEmpty(response.ContentEncoding) ? Encoding.GetEncoding(response.ContentEncoding) : Encoding.UTF8;
Stream stream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(stream, encoding))
{
responseText = reader.ReadToEnd();
}
}
catch (Exception ex)
{ responseText = ex.Message; }
if (this.ResponseComplate != null)
{
this.ResponseComplate(this, new ResponseComplatedArgs(responseText, m_ResponseHeaders, code));
}
}
public void Invoke()
{
base.Send(this.ActionMode, this.Url, this.QueryText, this.RequestHeaders, this.Encoding.GetBytes(this.BodyData), null, this.Cookies, this.TimeOut, new AsyncCallback(RespCallback));
}
}
public class ResponseComplatedArgs:EventArgs
{
private string m_Data ="";
public string ResponseData{get{return m_Data;}}
private WebHeaderCollection m_Headers = new WebHeaderCollection();
public WebHeaderCollection ResponseHeaders { get { return m_Headers; } }
public HttpStatusCode StatusCode { get; private set; }
public ResponseComplatedArgs()
{}
public ResponseComplatedArgs(string data, WebHeaderCollection headers,HttpStatusCode code)
{
m_Data=data;
m_Headers = headers;
this.StatusCode = code;
}
}
}
对开源中国的通信进行实装(未完成)。
using System;
using System.Text;
using System.Net;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
namespace OCMove
{
public class OSChina
{
#region Actions
private HttpAction ACTION_LOGIN = new HttpAction(HttpMethodType.POST, "https://www.oschina.net/action/user/hash_login");
private HttpAction ACTION_DONGTAN = new HttpAction(HttpMethodType.POST, "http://www.oschina.net/action/tweet/pub");
private HttpAction ACTION_REFRESH = new HttpAction(HttpMethodType.GET, "http://www.oschina.net/widgets/check-top-log?last=undefined");
private HttpAction ACTION_ANSWER = new HttpAction(HttpMethodType.POST, "http://my.oschina.net/action/tweet/rpl");
private HttpAction ACTION_MY_INFO = new HttpAction(HttpMethodType.POST, "http://www.oschina.net/action/api/my_information");
#endregion//Actions
#region Constructors
public OSChina()
{
Init();
}
public OSChina(string email,string pwd)
{
this.Email = email;
this.Pwd = pwd;
Init();
}
private void Init()
{
ACTION_LOGIN.ResponseComplate += new EventHandler<ResponseComplatedArgs>(ACTION_LOGIN_ResponseComplate);
ACTION_MY_INFO.ResponseComplate += new EventHandler<ResponseComplatedArgs>(ACTION_MY_INFO_ResponseComplate);
}
#endregion //
#region Properties
public bool HasLogined
{
get;
private set;
}
public string Email
{
get;
set;
}
public string Pwd
{
get;private set;
}
public int UserCode
{
get;
private set;
}
public string UserName
{
get;
private set;
}
public Uri HomePage
{
get;
private set;
}
public CookieCollection Cookies
{
get;
private set;
}
public Cookie OscidCookie
{
get;
private set;
}
#endregion //Properties
#region Methods
#region LoginAction
public event EventHandler<ResponseComplatedArgs> LoginComplated;
public virtual void Login()
{
ACTION_LOGIN.RequestHeaders.Add(HttpRequestHeader.Referer, "https://www.oschina.net/home/login?goto_page=http%3A%2F%2Fwww.oschina.net%2F");
ACTION_LOGIN.BodyData = string.Format("email={0}&pwd={1}&keep_login=1",this.Email,this.Pwd);
ACTION_LOGIN.Cookies = new CookieContainer();
ACTION_LOGIN.Invoke();
}
void ACTION_LOGIN_ResponseComplate(object sender, ResponseComplatedArgs e)
{
if( e.StatusCode == HttpStatusCode.OK)
{
this.HasLogined = true;
this.Cookies = ACTION_LOGIN.Cookies.GetCookies(new Uri("https://www.oschina.net"));
foreach (Cookie c in this.Cookies)
{
if ("oscid".Equals(c.Name))
{
this.OscidCookie = c;
break;
}
}
}
if (this.LoginComplated != null)
{
this.LoginComplated(this,e);
}
}
#endregion //Login
public virtual void GetMyInformation()
{
ACTION_MY_INFO.Cookies = new CookieContainer();
ACTION_LOGIN.Cookies.Add( this.OscidCookie);
ACTION_MY_INFO.Invoke();
}
void ACTION_MY_INFO_ResponseComplate(object sender, ResponseComplatedArgs e)
{
}
#endregion//Methods
}
}
现在进行下简单验证,首先是登录。
string email = "******@gmail.com";
string pwd = "****";
OSChina osc = new OSChina(email,pwd.ToSHA1());
osc.LoginComplated += new EventHandler<ResponseComplatedArgs>(osc_LoginComplated);
osc.Login();