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

[经验分享] 90%使用WebDAV开发的Exchange邮件管理(二)——Hello,获取未读邮件数!

[复制链接]

尚未签到

发表于 2015-9-10 12:54:29 | 显示全部楼层 |阅读模式
                   90%使用WebDAV开发的Exchange邮件管理(二)
                                                                     ——Hello,获取未读邮件数!
     
        但凡学习一种新的编程语言,书中的第一个范例都是经典的“Hello,World”。初次尝试使用WebDAV,也得找一个基本的例子试试,以对其有一个感性的认识,我的例子是用来获取未读邮件数目的,所以就有了如上的小标题。
        首先在SDK中搜索WebDAV,找到一些范例,看了看,有一个Getting a List of Folders (WebDAV) ,和所要实现的功能有点贴近。不管三七二十一。运行一下代码吧:  
  1 DSC0000.gif using System;
  2using System.Net;
  3using System.IO;
  4using System.Text;
  5using System.Xml;
  6
  7namespace ExchangeSDK.Snippets.CSharp
  8 DSC0001.gif DSC0002.gif DSC0003.gif {
  9 DSC0004.gif    class GettingListOfFoldersWebDAV
10 DSC0005.gif DSC0006.gif    {
11      [STAThread]
12      static void Main(string[] args)
13      {
14         // Variables.
15         System.Net.HttpWebRequest Request;
16         System.Net.WebResponse Response;
17         System.Net.CredentialCache MyCredentialCache;
18         string strRootURI = "http://server/TestStore/TestStoreFolder/";
19         string strUserName = "UserName";
20         string strPassword = "!Password";
21         string strDomain = "Domain";
22         string strQuery ="";
23         byte[] bytes = null;
24         System.IO.Stream RequestStream = null;
25         System.IO.Stream ResponseStream = null;
26         System.Xml.XmlTextReader XmlReader = null;
27
28         try
29         {
30            // Build the SQL query.
31            strQuery = "<?xml version=\"1.0\"?><D:searchrequest xmlns:D = \"DAV:\" >";
32            strQuery += "<D:sql>SELECT \"DAV:href\" FROM scope('hierarchical traversal of \"";
33            strQuery += strRootURI + "\"')</D:sql></D:searchrequest>";
34
35            // Create a new CredentialCache object and fill it with the network
36            // credentials required to access the server.
37            MyCredentialCache = new System.Net.CredentialCache();
38            MyCredentialCache.Add( new System.Uri(strRootURI),
39               "NTLM",
40               new System.Net.NetworkCredential(strUserName, strPassword, strDomain)
41               );
42
43            // Create the HttpWebRequest object.
44            Request = (System.Net.HttpWebRequest)HttpWebRequest.Create(strRootURI);
45
46            // Add the network credentials to the request.
47            Request.Credentials = MyCredentialCache;
48
49            // Specify the method.
50            Request.Method = "SEARCH";
51
52            // Encode the body using UTF-8.
53            bytes = Encoding.UTF8.GetBytes((string)strQuery);
54
55            // Set the content header length.  This must be
56            // done before writing data to the request stream.
57            Request.ContentLength = bytes.Length;
58
59            // Get a reference to the request stream.
60            RequestStream = Request.GetRequestStream();
61
62            // Write the SQL query to the request stream.
63            RequestStream.Write(bytes, 0, bytes.Length);
64
65            // Close the Stream object to release the connection
66            // for further use.
67            RequestStream.Close();
68
69            // Set the content type header.
70            Request.ContentType = "text/xml";
71
72            // Send the SEARCH method request and get the
73            // response from the server.
74            Response = (HttpWebResponse)Request.GetResponse();
75
76            // Get the XML response stream.
77            ResponseStream = Response.GetResponseStream();
78
79            // Create the XmlTextReader object from the XML
80            // response stream.
81            XmlReader = new XmlTextReader(ResponseStream);
82
83            // Read through the XML response, node by node.
84            while(XmlReader.Read())
85            {
86               // Look for the opening DAV:href node.  The DAV: namespace is
87               //typically assigned the a: prefix in the XML response body.
88               if(XmlReader.Name == "a:href")
89               {
90                  // Advance the reader to the text node.
91                  XmlReader.Read();
92
93                  // Display the value of the DAV:href text node.
94                  Console.WriteLine("Value: " + XmlReader.Value);
95                  Console.WriteLine("");
96
97                  //Advance the reader to the closing DAV:href node.
98                  XmlReader.Read();
99 DSC0007.gif                }
100            }
101
102            // Clean up.
103            XmlReader.Close();
104            ResponseStream.Close();
105            Response.Close();
106
107         }
108         catch(Exception ex)
109         {
110            // Catch any exceptions. Any error codes from the SEARCH
111            // method request on the server will be caught here, also.
112            Console.WriteLine(ex.Message);
113         }
114      }
115   }
116 DSC0008.gif }
117
118         31~33行构造了Web Storage System SQL查询的XML,去头去尾,对我们比较关键就是SELECT "DAV:href" FROM scope('hierarchical traversal of "+strRootURI+')。SQL查询相信大家都会的了。&#8220;DAV:href&#8221;是DAV属性,表示条目的URL。其他的还包括:DAV:displayname(条目通用名称)、DAV:isfolder(表示这个条目是否文件夹),DAV:则是Web Storage System(WSS)的名称空间了,当然还有如下的名称空间:&#8220;http://schemas.microsoft.com/exchange/&#8221;,&#8220;urn-schemas:calendar:&#8221;,&#8220;Urn:schemas:httpmail:&#8221;等等。各项具体属性可以在Exchange SDK中根据索引查找。scope是用于指定查询的位置和深度。而strRootURI则是要查询条目的路径。在Exchange中的每个条目都可以通过URL访问,其所有编程任务也是以URL为基础的。URL分为文件URL和HTTP URL,形式分别如下:
file://./backofficestorage/<domain-name>/<public -folder-tree-name>/<path>
http://<server-name>/<virtual-directory>/<virtual-path>  
        因此,我们可以拼接查询未读邮件数的查询语句

    strQuery = "<?xml version=\"1.0\"?><D:searchrequest xmlns:D = \"DAV:\" >"
                    + "<D:sql>SELECT \"DAV:displayname\",\"urn:schemas:httpmail:unreadcount\" FROM \"" + strRootURI + "\""
                    + "WHERE \"DAV:ishidden\" = false AND \"DAV:isfolder\" = false"
                    + "</D:sql></D:searchrequest>"; 其中strRootURI="http://servername/exchagne/useralias" 。
        37~41行创建了用于访问资源的NTLM的凭据。60行以后则是通过将服务器返回XML解析,通过查找XML节点中的属性得到查询结果。在这里,我实在搞不清楚XML节点属性名称有哪些,且在不同的方法下,形如a:displayname的前缀到底是指DAV:还是其他的名称空间,就干脆把后半段的方法改写了,直接将XML输出到文件中,方便查看。(顺便也学习了一下System.IO)

    // Get the XML response stream.
                ResponseStream = Response.GetResponseStream();


                System.IO.StreamReader reader = new StreamReader(ResponseStream);
                string xml = reader.ReadToEnd();
               
                FileInfo textfile=new FileInfo(@"C:\1.xml");
            
               
                StreamWriter outStream=textfile.CreateText();   
                    
                outStream.Write(xml);
                outStream.Close();最后,根据各种不同查询的尝试,及得到的XML文件的反馈,最终得到完整的查询未读邮件代码如下:

private int GetUnReadMailCount()
        {
            string url=ConfigurationSettings.AppSettings["ExchangeServer"];   
            System.Net.HttpWebRequest Request;
            System.Net.WebResponse Response;
            System.Net.CredentialCache MyCredentialCache;
            string strRootURI = url+"/"+User.Identity.Name;
            string strUserName = User.Identity.Name;
            string strPassword = DAL.Data.UserModel.SelectByUserId(User.Identity.Name).Password.Trim();
            string strDomain = ConfigurationSettings.AppSettings["ExchangeDomain"];
            string strQuery ="";
            byte[] bytes = null;
            System.IO.Stream RequestStream = null;
            System.IO.Stream ResponseStream = null;
            XmlDocument ResponseXmlDoc = null;
            XmlNodeList HrefNodes= null;
            XmlNodeList SizeNodes= null;
            int count=0;
            try
            {
                // Build the SQL query.
                strQuery = "<?xml version=\"1.0\"?><D:searchrequest xmlns:D = \"DAV:\" >"
                    + "<D:sql>SELECT \"DAV:displayname\",\"urn:schemas:httpmail:unreadcount\" FROM \"" + strRootURI + "\""
                    //    +"where \"DAV:contentclass\"=\"urn:schemas:httpmail:read \""            
                    //        + "WHERE \"DAV:ishidden\" = false AND \"DAV:isfolder\" = false"
                    + "</D:sql></D:searchrequest>";

                // Create a new CredentialCache object and fill it with the network
                // credentials required to access the server.
                MyCredentialCache = new System.Net.CredentialCache();
                MyCredentialCache.Add( new System.Uri(strRootURI),
                    "NTLM",
                    new System.Net.NetworkCredential(strUserName, strPassword, strDomain)
                    );

                // Create the HttpWebRequest object.
                Request = (System.Net.HttpWebRequest)HttpWebRequest.Create(strRootURI);

                // Add the network credentials to the request.
                Request.Credentials = MyCredentialCache;

                // Specify the method.
                Request.Method = "SEARCH";

                // Encode the body using UTF-8.
                bytes = Encoding.UTF8.GetBytes((string)strQuery);

                // Set the content header length.  This must be
                // done before writing data to the request stream.
                Request.ContentLength = bytes.Length;

                // Get a reference to the request stream.
                RequestStream = Request.GetRequestStream();

                // Write the SQL query to the request stream.
                RequestStream.Write(bytes, 0, bytes.Length);

                // Close the Stream object to release the connection
                // for further use.
                RequestStream.Close();

                // Set the content type header.
                Request.ContentType = "text/xml";

                // Send the SEARCH method request and get the
                // response from the server.
                Response = (HttpWebResponse)Request.GetResponse();
        
                // Get the XML response stream.
                ResponseStream = Response.GetResponseStream();
            
                // Create the XmlDocument object from the XML response stream.
                ResponseXmlDoc = new XmlDocument();
                ResponseXmlDoc.Load(ResponseStream);
                HrefNodes = ResponseXmlDoc.GetElementsByTagName("a:displayname");
                SizeNodes = ResponseXmlDoc.GetElementsByTagName("d:unreadcount");
                for(int i=0;i<HrefNodes.Count;i++)
                {
                    if(HrefNodes.InnerText=="收件箱")
                        count=int.Parse(SizeNodes.InnerText);
                }
                ResponseStream.Close();
                Response.Close();
            }
            catch(Exception)
            {
                // Catch any exceptions. Any error codes from the SEARCH
                // method request on the server will be caught here, also.
                return -1;
            }
            return count;
        }

名词解释:
Web Storage System:是一项数据库技术,随着Windows2000操作系统引入的,可用于存储、共享和管理很多类型的数据。WSS被组织为文件夹体系的形式。

运维网声明 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-111967-1-1.html 上篇帖子: javascript调用Exchange webservice的例子 下篇帖子: Inject js code to exchange 2013
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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