桃李不言,下自成蹊;软件工程师,非某语言的程序员

获取exchange 2007 中的用户配额使用量(即用户已使用的邮箱空间)

在2003版本中,获取邮箱已使用的空间是通过webdav循环所有的文件夹获取所有的文件夹的邮件的大小之和。消耗资源较大。。
在2007版中,我们通过webservice获取所有的文件夹,根据文件夹的信息来累计文件夹已使用大小。 但是消耗资源也较大,每次在第一次访问的时候大概在3s左右。那么有没有更好更快的办法呢 ?

当然是有的,首先考虑的问题,那么owa自己是怎么做呢,他自己有没有获取这些数据呢?


既然它可以取到?那么我们自然也可以通过它的方式取到罗?
测试开始。。。
用fiddler2 监控一下 ,发现了以下可疑的链接?



进一步查看:

看上图的文字?对了这就是我们要的数据了,就是这个请求了。。
前面一个数字是byte数,后面是显示的文字,转换成了kb,当大于1mb时就转换成mb

那接下来的事就比较简单了。就是如何来构建这个请求了。我们来仔细看下这个请求。见下图


上图可知,请求只post方式:

url地址为:http://mail.lab.com/owa/ev.owa?oeh=1&ns=Tree&ev=GetMailboxUsage

其中http://mail.lab.com/owa owa的根路径

需要下列的文件头:

Accept: */*
Accept-Language: zh-cn
Referer: http://mail.lab.com/owa/
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022)
Host: mail.lab.com
Content-Length: 9
Connection: Keep-Alive
Pragma: no-cache
Cookie: UserContext=5148366543cf495697cfa3dcb434d772
Authorization: Basic bGFiXHN5czpBcHAxMjM0

删除没必要的文件头(一个一个删除来测试是否必要)

User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022)
Host: mail.lab.com
Content-Length: 9
Authorization: Basic bGFiXHN5czpBcHAxMjM0  

其中:Authorization为变量,即当前用户的登录信息

请求的body
<params/>

好了知道了这些就好办了,
通过httpResponse,和httpRequest来构建这个请求吧
以下是详细代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Text.RegularExpressions;
using System.IO;

namespace Beyondbit.Components.Exchange
{
    
public class UseAgeHelp
    {
        
public UseAgeHelp(string account, string password, string domain)
        {
            _account 
= account;
            _password 
= password;
            _domain 
= domain;
        }

        
private string _account = "";
        
private string _password = "";
        
private string _domain = "";

        
        
private string GetMailboxUsageString()
        {
            
string url = Config.ExchangeServerPath + "ev.owa?oeh=1&ns=Tree&ev=GetMailboxUsage";
            WebResponse ret 
= HttpCallGetMailboxUsage(url);
            Stream stream 
= ret.GetResponseStream();
            StreamReader sr 
= new StreamReader(stream, Encoding.GetEncoding("UTF-8"));
            
string htmlstr = sr.ReadToEnd();
            
return htmlstr;
        }

        
/// <summary>
        
/// 获取用户已经使用的容量
        
/// </summary>
        
/// <returns>返回已使用容量的byte数 /1024 单位为kb  再/1024 单位为 MB</returns>
        public int GetMailboxUsage()
        {
            
string usageString = GetMailboxUsageString();
            Match mc 
= Regex.Match(usageString, @"^<div id=mbUsg>([\d]+)</div><div id=dspMbUsg>([\d|\w|\W]+)</div>$");
            
return Convert.ToInt32(mc.Groups[1].Value);
        }
        
/// <summary>
        
/// 获取用户已经使用的容量
        
/// </summary>
        
/// <returns>返回已使用容量的原始文本</returns>
        public string GetMailboxUsageSourceString()
        {
            
string usageString = GetMailboxUsageString();
            Match mc 
= Regex.Match(usageString, @"^<div id=mbUsg>([\d]+)</div><div id=dspMbUsg>([\d|\w|\W]+)</div>$");
            
return mc.Groups[0].Value;
        }

        
/// <summary>
        
/// 获取用户已经使用的容量
        
/// </summary>
        
/// <returns>返回已使用容量的显示文本</returns>
        public string GetMailboxUsageDisplayString()
        {
            
string usageString = GetMailboxUsageString();
            Match mc 
= Regex.Match(usageString, @"^<div id=mbUsg>([\d]+)</div><div id=dspMbUsg>([\d|\w|\W]+)</div>$");
            
return mc.Groups[2].Value;
        }

        
private WebResponse HttpCallGetMailboxUsage(string url)
        {
            HttpWebRequest Req;

            
try
            {
                
//构建当前用户的凭据 ,以下两行
                System.Net.CredentialCache MyCredentialCache = new System.Net.CredentialCache();
                MyCredentialCache.Add(
new Uri(url), "basic"new System.Net.NetworkCredential(_account, _password, _domain));

                
//生成一个请求类
                Req = (System.Net.HttpWebRequest)HttpWebRequest.Create(url);
                
//把当前凭据设置成已经建立好的凭据
                Req.Credentials = MyCredentialCache;
                
//设置请求的方式为POST
                Req.Method = "POST";
                
//该项可有可无
                Req.ContentType = "application/x-www-form-urlencoded";
                Req.AllowAutoRedirect 
= true;
                
//用户客户端类型,我们把它设置成IE
                Req.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022)";

                
//构建请求的消息体body
                byte[] paraStream = Encoding.UTF8.GetBytes("<params/>");//写死body的内容
                Req.ContentLength = paraStream.Length;
                Stream newStream 
= Req.GetRequestStream();
                newStream.Write(paraStream, 
0, paraStream.Length);
                newStream.Close();
                
//Stream request =Req.GetRequestStream();
                
//request.Write(

            }
            
catch (Exception ex)
            {
                
throw ex;
            }

            
try
            {
                
//发起请求,并返回Response的对象
                WebResponse result = Req.GetResponse();

                
return result;

            }
            
catch (Exception ex)
            {

                
throw ex;
            }
        }
    }
}


posted @ 2008-06-02 21:02  假正经哥哥  阅读(2261)  评论(0编辑  收藏  举报