ASP.NET 取得 MSN 的聯絡人清單 (Get MSN Mail Contacts)
繼
ASP.NET 取得 GMAIL 的聯絡人清單 (Get Google Contacts List)
以及
ASP.NET 取得 Yahoo! 的聯絡人清單 (Get Yahoo Mail Contacts)
兩篇文章之後,這一篇則是針對大家常用的Windows Live! Messenger取得所有連絡人的資訊。
其實跟Google及Yahoo都是類似的做法,主要都是使用HTTP protocol中的Request及Response取得瀏覽器以及伺服器往來的資訊。最後取得連絡人的資料後(通常是csv,或是通用xml格式)。
而這次要取得Windows Live Messenger連絡人的方式,老實說比以往還要複雜一些,因為要自己包裝SOAP envelope作為server response file(srf檔),最後再取得伺服器的回傳值(ticket)。這邊有個小問題跟Yahoo是一樣的,回傳的ticket開頭最前面的2個字元是 "t=",與當初取得Yahoo!聯絡人清單類似,只是Yahoo所得到的token前面有 "Y=" 兩個字元必須移除罷了。感謝SourceForge上讓我找到了OpenContacts.NET,否則我大概要多花一倍以上的時間去研讀各家的API。以下直接把取得ticket及擷取MSN連絡人的方法直接貼出來,這部份我有修改了一些OpenContacts.NET的內容,不過內容上並沒有什麼差異,主要是差在輸出的格式罷了 : )
WindowsLiveTicketAcquirer : 取得MSN伺服器回傳的ticket(認證)
internal class WindowsLiveTicketAcquirer {
private const string applicationId = "10"; // An arbitrary value that will be defined in the next non-alpha release
/// <summary>
/// generate SOAP envelope
/// </summary>
/// <param name="userName">user name</param>
/// <param name="password">password</param>
/// <returns>ticket</returns>
public String GetTicket(String userName, String password) {
string soapEnvelope =
@"<s:Envelope
xmlns:s = ""http://www.w3.org/2003/05/soap-envelope""
xmlns:wsse = ""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""
xmlns:saml = ""urn:oasis:names:tc:SAML:1.0:assertion""
xmlns:wsp = ""http://schemas.xmlsoap.org/ws/2004/09/policy""
xmlns:wsu = ""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd""
xmlns:wsa = ""http://www.w3.org/2005/08/addressing""
xmlns:wssc = ""http://schemas.xmlsoap.org/ws/2005/02/sc""
xmlns:wst = ""http://schemas.xmlsoap.org/ws/2005/02/trust"">
<s:Header>
<wlid:ClientInfo xmlns:wlid = ""http://schemas.microsoft.com/wlid"">
<wlid:ApplicationID>" + applicationId + @"</wlid:ApplicationID>
</wlid:ClientInfo>
<wsa:Action s:mustUnderstand = ""1"">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>
<wsa:To s:mustUnderstand = ""1"">https://dev.login.live.com/wstlogin.srf</wsa:To>
<wsse:Security>
<wsse:UsernameToken wsu:Id = ""user"">
<wsse:Username>" + userName + @"</wsse:Username>
<wsse:Password>" + password + @"</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</s:Header>
<s:Body>
<wst:RequestSecurityToken Id = ""RST0"">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>http://live.com</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wsp:PolicyReference URI = ""MBI""></wsp:PolicyReference>
</wst:RequestSecurityToken>
</s:Body>
</s:Envelope>";
const string url = @"https://dev.login.live.com/wstlogin.srf";
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=UTF-8";
request.Timeout = 10 * 1000; // Wait for at most 10 seconds
byte[] bytes = Encoding.UTF8.GetBytes(soapEnvelope);
request.GetRequestStream().Write(bytes, 0, bytes.Length);
request.GetRequestStream().Close();
WebResponse response;
response = request.GetResponse();
string xml;
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
xml = reader.ReadToEnd();
}
response.Close();
XmlDocument document = new XmlDocument();
document.LoadXml(xml);
XmlNamespaceManager nsManager = new XmlNamespaceManager(document.NameTable);
nsManager.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
XmlNode node = document.SelectSingleNode(@"//wsse:BinarySecurityToken/text()", nsManager);
if (node == null) {
return null; // The wsse:BinarySecurityToken element is missing. Examine the xml for error information
}
else {
return node.Value;
}
}
}
LiveExtract : 取得MSN連絡人的主程式
WindowsLiveTicketAcquirer ticketAcq = new WindowsLiveTicketAcquirer();
String ticket = ticketAcq.GetTicket(userName, password).Substring(2);
UriBuilder urib = new UriBuilder();
urib.Scheme = SCHEME;
urib.Path = String.Format("/{0}/LiveContacts", userName);
urib.Host = HOST;
urib.Port = PORT;
HttpWebRequest req = WebRequest.Create(urib.Uri) as HttpWebRequest;
req.Headers.Add(HttpRequestHeader.Authorization, String.Format("WLID1.0 t=\"{0}\"", ticket));
WebResponse response = req.GetResponse();
if (response.ContentLength != 0) {
XmlDocument doc = new XmlDocument();
doc.Load(response.GetResponseStream());
#region 取得所有的 Contacts 並依結果建立 WindowsLiveContact 類別
XmlNodeList contacts = doc.SelectNodes("/LiveContacts/Contacts/Contact");
this.liveContactList = new List<WindowsLiveContact>();
XmlNode firstName, lastName, nickName, uniqueName, sortName, displayName, email, windowsLiveID, groupName;
foreach (XmlNode node in contacts) {
firstName = node.SelectSingleNode("Profiles/Personal/FirstName");
lastName = node.SelectSingleNode("Profiles/Personal/LastName");
nickName = node.SelectSingleNode("Profiles/Personal/NickName");
uniqueName = node.SelectSingleNode("Profiles/Personal/UniqueName");
sortName = node.SelectSingleNode("Profiles/Personal/SortName");
displayName = node.SelectSingleNode("Profiles/Personal/DisplayName");
email = node.SelectSingleNode("Emails/Email/Address");
windowsLiveID = node.SelectSingleNode("WindowsLiveID");
//groupName = node.SelectSingleNode("Tags/Tag");
WindowsLiveContact lc = new WindowsLiveContact();
lc.FirstName = firstName == null ? string.Empty : firstName.InnerText;
lc.LastName = lastName == null ? string.Empty : lastName.InnerText;
lc.NickName = nickName == null ? string.Empty : nickName.InnerText;
lc.UniqueName = uniqueName == null ? string.Empty : uniqueName.InnerText;
lc.SortName = sortName == null ? string.Empty : sortName.InnerText;
lc.DisplayName = displayName == null ? string.Empty : displayName.InnerText;
lc.Email = email == null ? string.Empty : email.InnerText;
lc.WindowsLiveID = windowsLiveID == null ? string.Empty : windowsLiveID.InnerText;
lc.GroupName = string.Empty;
this.liveContactList.Add(lc);
}
this.sourceTable = new DataTable();
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.DisplayName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.Email));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.FirstName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.FullName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.GroupName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.LastName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.NickName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.SortName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.UniqueName));
this.sourceTable.Columns.Add(new DataColumn(ContactColumn.WindowsLiveID));
DataRow row = null;
foreach (WindowsLiveContact lc in this.liveContactList) {
row = this.sourceTable.NewRow();
row[ContactColumn.DisplayName] = lc.DisplayName;
row[ContactColumn.Email] = lc.Email;
row[ContactColumn.FirstName] = lc.FirstName;
row[ContactColumn.FullName] = lc.FullName;
row[ContactColumn.GroupName] = lc.GroupName;
row[ContactColumn.LastName] = lc.LastName;
row[ContactColumn.NickName] = lc.NickName;
row[ContactColumn.SortName] = lc.SortName;
row[ContactColumn.UniqueName] = lc.UniqueName;
row[ContactColumn.WindowsLiveID] = lc.WindowsLiveID;
this.sourceTable.Rows.Add(row);
}
this.sourceTable.AcceptChanges();
#endregion
}

1 意見:
你好:
我在写一个关于windows live contacts的程序。有些问题想请教你
我的email/msn:knyanyan@hotmail.com
方便的话能否和我联系。谢谢
阎彦
張貼意見