设为首页 收藏本站
查看: 629|回复: 0

[经验分享] How do I access my Outlook contacts from my web application?

[复制链接]

尚未签到

发表于 2015-9-13 09:02:41 | 显示全部楼层 |阅读模式
Question
  How do I access my Outlook contacts from my web application?
Short Answer
  You don't, well at least you shouldn't (It is theoretically possible to access Outlook data from a web application, assuming Outlook is installed and the profile you wish to access data from is setup on the web server).
Long Answer
  To address this question we need to realize that Outlook is a client application which is only a front end and local cache for a mail server (typically exchange server). Most web applications are server applications and thus run on servers which usually don't have client applications, such as Outlook, installed on them. Perhaps a better question would be "How do I access my Exchange contacts from my web application?".
  With that in mind lets explore a couple possible solutions for accessing data (not really Outlook data) from the Exchange server.

  • WebDAV - Protocol that Outlook Web Access (OWA) uses to access your Exchange store
  • Exchange Web Services (EWS) - New services added to Exchange 2007 to allow access to most data
  • Active Directory Services Interface (ADSI) - For accessing general Exchange user data information (i.e. access the Global Address List)
  These are just three common technologies for accessing data on a Exchange server, for more details see the Exchange Server Development Center or Overview of Programming Features for Exchange Server. To provide a more complete example I've included some code samples and links for each of the three technologies. The code examples demonstrate how to do find contacts using each of the three methods. Keep in mind these samples can be extended to other data types such as mail and appointments, with the exception of ADSI. All the code samples are written in C# and write the data to the console, they can easily be converted to be used by an ASP.Net web application. Also remember to substitute <ExchangeServer>, <username>, <password>, and <domain> with the appropriate values for your Exchange server.
WebDAV
  The sample retrieves all contacts from an exchange store which have a first name beginning with 'wes'. Keep in mind before making any Exchange WebDAV requests you must make an forms authorization request first (assuming the Exchange server has forms authorization enabled, which seems to generally be the case). You need to make the authorization request to get the set of authorization cookies to use with any subsequent WebDAV requests.

  using System;
  using System.IO;
  using System.Net;
  using System.Text;
  using System.Xml;
  
  // When Exchange is setup for Forms Authentication you need to do the login separately
  public static CookieCollection GetAuthCookies(string server, NetworkCredential credentials)
  {
  // URI to OWA authorization dll
  string authURI = string.Format("{0}/exchweb/bin/auth/owaauth.dll",
  server, credentials.UserName);
  
  // Get byte stream of the post request
  byte[] bytes = Encoding.UTF8.GetBytes(string.Format(
  "destination={0}/exchange/{1}&username={2}\\{1}&password={3}",
  server, credentials.UserName, credentials.Domain, credentials.Password));
  
  HttpWebRequest request = WebRequest.Create(authURI) as HttpWebRequest;
  request.Method = "POST";
  request.ContentType = "application/x-www-form-urlencode";
  request.CookieContainer = new CookieContainer();
  request.ContentLength = bytes.Length;
  request.AllowAutoRedirect = false;
  
  using (Stream requestStream = request.GetRequestStream())
  requestStream.Write(bytes, 0, bytes.Length);
  
  // Get response cookies - keep in mind this may throw exceptions
  using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
  return response.Cookies;
  }
  
  public static void PrintContactsUsingExchangeWebDAV()
  {
  string server = "http<s>://<ExchangeServer>";
  NetworkCredential credentials = new NetworkCredential("<username>", "<password>", "<domain>");
  string uri = string.Format("{0}/exchange/{1}", server, credentials.UserName);
  
  // Create a byte stream of the SQL query to run against the server
  // This query searches for contacts with the givenName the begins with 'wes'
      // Link to Exchange store property names
  byte[] contents = Encoding.UTF8.GetBytes(string.Format(
  @"<?xml version=""1.0""?>
          <g:searchrequest xmlns:g=""DAV:"">
              <g:sql>
                  SELECT
                      ""urn:schemas:contacts:sn"", ""urn:schemas:contacts:givenName"",
                      ""urn:schemas:contacts:email1"", ""urn:schemas:contacts:telephoneNumber""
                  FROM
                      Scope('SHALLOW TRAVERSAL OF ""{0}/exchange/{1}/contacts""')
                  WHERE
                      ""urn:schemas:contacts:givenName"" LIKE 'wes%'
              </g:sql>
          </g:searchrequest>",
  server, credentials.UserName));
  
  HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
  request.Credentials = credentials;
  request.Method = "SEARCH";
  request.ContentLength = contents.Length;
  request.ContentType = "text/xml";
  request.CookieContainer = new CookieContainer();
  // Keep in mind you may actually want to cache these cookies for other requests
  request.CookieContainer.Add(GetAuthCookies(server, credentials));
  
  using (Stream requestStream = request.GetRequestStream())
  requestStream.Write(contents, 0, contents.Length);
  
  using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
  using (Stream responseStream = response.GetResponseStream())
  {
  // Process the response as an XML document
  XmlDocument document = new XmlDocument();
  document.Load(responseStream);
  
  foreach (XmlElement element in document.GetElementsByTagName("a:prop"))
  {
  // Do work with data returned for each contact
  Console.WriteLine("Name:  {0} {1}\nEmail: {2}\nPhone: {3}",
  (element["d:givenName"] != null ? element["d:givenName"].InnerText : ""),
  (element["d:sn"] != null ? element["d:sn"].InnerText : ""),
  (element["d:email1"] != null ? element["d:email1"].InnerText : ""),
  (element["d:telephoneNumber"] != null ? element["d:telephoneNumber"].InnerText : ""));
  }
  }
  }
  Helpful WebDAV Links:
  Infinitec Exchange posts - C# and JavaScript forms authentication examples
Marc Charbonneau - Using .NET and WebDAV to access an Exchange server
Hitchhiker guide to enterprise development - Programmatically accessing to OWA through Web Dav
Exchange store property names
Exchange Web Services
  This sample code goes through the process of creating a Exchange web service FindItem request. In essentially searches through the contact folder looking for any contact with first name starting with 'wes'.

  using System;
  using System.Net;
  // Generate Exchange Web Services proxy classes by adding a VS web
  // reference to http<s>://<ExchangeServer>/EWS/Services.wsdl
  // then add a using reference to your proxy classes
  
  public static void PrintContactsUsingExchangeWebServices()
  {
  ExchangeServiceBinding esb = new ExchangeServiceBinding();
  esb.Credentials = new NetworkCredential("<username>", "<password>", "<domain>");
  esb.Url = @"http<s>://<ExchangServer>/EWS/Exchange.asmx";
  
  // Tell it you want all the item properties
  ItemResponseShapeType itemProperties = new ItemResponseShapeType();
  itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;
  
  // Tell it you only want to look in the contacts folder
  DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
  folderIDArray[0] = new DistinguishedFolderIdType();
  folderIDArray[0].Id = DistinguishedFolderIdNameType.contacts;
  
  PathToUnindexedFieldType field = new PathToUnindexedFieldType();
  field.FieldURI = UnindexedFieldURIType.contactsGivenName;
  
  ConstantValueType fieldValue = new ConstantValueType();
  fieldValue.Value = "wes";
  
  // Look for contacts which have a given name that begins with 'wes'
  ContainsExpressionType expr = new ContainsExpressionType();
  expr.ContainmentModeSpecified = true;
  expr.ContainmentMode = ContainmentModeType.Prefixed;
  expr.ContainmentComparisonSpecified = true;
  expr.ContainmentComparison = ContainmentComparisonType.IgnoreCase;
  expr.Constant = fieldValue;
  expr.Item = field;
  
  RestrictionType restriction = new RestrictionType();
  restriction.Item = expr;
  
  // Form the FindItem request
  FindItemType findItemRequest = new FindItemType();
  findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
  findItemRequest.ItemShape = itemProperties;
  findItemRequest.ParentFolderIds = folderIDArray;
  findItemRequest.Restriction = restriction;
  
  // Send the request and get the response
  FindItemResponseType findItemResponse = esb.FindItem(findItemRequest);
  
  if (findItemResponse.ResponseMessages.Items.Length > 0)
  {
  FindItemResponseMessageType responseMessage =
  findItemResponse.ResponseMessages.Items[0] as FindItemResponseMessageType;
  ArrayOfRealItemsType realItems =
  responseMessage.RootFolder.Item as ArrayOfRealItemsType;
  
  foreach (ContactItemType contact in realItems.Items)
  {
  // Do work with data returned for each contact
  Console.WriteLine("Name:  {0} {1}\nEmail: {2}\nPhone: {3}",
  contact.GivenName, contact.Surname,
  (contact.EmailAddresses != null && contact.EmailAddresses.Length > 0 ?
  contact.EmailAddresses[0].Value : ""),
  (contact.PhoneNumbers != null && contact.PhoneNumbers.Length > 0 ?
  contact.PhoneNumbers[0].Value : ""));
  }
  }
  }
  Useful Exchange Web Service Links:
  MSDN Exchange Web Services Reference
Stephen Griffin - Exchange Web Services and MAPI Props
Eric Lee - Exchange Server 2007 Web Service API for Developers
Active Directory Services Interface
  This is a very simplified .Net sample of doing a search in the default active directory for any users that have a first name beginning with 'wes'. Keep in mind that this uses the default active directory on the machine you are running on, see DirectorySearcher.SearchRoot for more details. If you need to specify a particular machine/directory to start your search from then you need to create a DirectoryEntry and pass that to the DirectorySearcher.

  using System;
  using System.DirectoryServices;
  
  // Get user information from your default active directory repository
  public static void PrintUsersFromADSI()
  {
  // Find any user that has a name that begins with 'wes'
  string filter = "(&(objectCategory=person)(objectClass=user)(givenName=wes*))";
  DirectorySearcher search = new DirectorySearcher(filter);
  foreach(SearchResult result in search.FindAll())
  {
  // Do work with data returned for each address entry
  DirectoryEntry entry = result.GetDirectoryEntry();
  Console.WriteLine("Name:  {0} {1}\nEmail: {2}\nPhone: {3}",
  entry.Properties["givenName"].Value,
  entry.Properties["sn"].Value,
  entry.Properties["mail"].Value,
  entry.Properties["telephonenumber"].Value);
  }
  }
  Useful ADSI/LDAP Links:
  
  InfiniTec - How to get the Global Address List programmatically
Amit Zinman - Creating a list of Users and their e-mail addresses
Steve Schofield - .NET sample LDAP query looking for a specific user name of (smith) and System.DirectoryServices namespace
Mow - PowerShell and Active Directory Part 1, Part 2, Part 3, Part 4, Part 5
  
  Disclaimer: The sample code described here is provided on an &#8220;as is&#8221; basis, without warranty of any kind, to the fullest extent permitted by law. It is for demonstration purposes only and is by no means production quality.

Published Tuesday, January 30, 2007 10:48 PM by puzzlehacker
Filed under: Tips and Tricks, .NET, Code, Outlook

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-112875-1-1.html 上篇帖子: 给Outlook添加BCC到指定邮箱的功能 下篇帖子: Outlook tasks
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表