繼
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 }
























