首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络编程-> C#/CSHARP教程
用C#访问Hotmail-.NET教程,.NET Framework
作者:网友供稿 点击:9
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
  pop邮件协议的优点在于它是一个开放的标准,有着完善的文档,这就使得编写pop邮件客户程序不那么困难,只要掌握了pop、smtp的基础知识,就可以写出代理程序来执行各种任务,例如过滤广告和垃圾邮件,或提供e-mail自动应答服务。

  hotmail是世界上影响最广的web邮件系统,遗憾的是,当我们要为hotmail编写独立的客户程序(不通过浏览器访问的客户程序)时,马上就会遇到hotmail不提供pop网关这一障碍。

  虽然hotmail不提供pop支持,但浏览器并非访问hotmail的唯一途径。例如,利用outlook express可以直接连接到标准的hotmail或msn信箱,提取、删除、移动或发送邮件。利用http包监视器,我们可以监视到outlook express和hotmail的通信过程,分析出客户程序如何连接到hotmail信箱。

  outlook express利用了一种通常称为httpmail的未公开的协议,借助一组http/1.1扩展访问hotmail。本文将介绍httpmail的一些特点以及利用c#客户程序访问hotmail的过程。本文的示例程序利用com互操作将xmlhttp用作一种传输服务。xmlhttp组件提供了一个完善的http实现,除了包括认证功能,还能够在发送http请求给服务器之前设置定制的http头。

  一、连接httpmail网关

  hotmail信箱默认的httpmail网关在http://services.msn.com/svcs/hotmail/httpmail.asp。httpmail协议实际上是一个标准的webdav服务,只不过尚未公开而已。在编写c#程序时,我们可以方便地调用.net框架在system.net名称空间中提供的各个tcp和http类。另外,由于我们要操作webdav,在c#环境下利用xmlhttp连接hotmail最为简便,只需引用一下msxml2组件就可以直接访问。注意在本文的代码片断中,带有下滑线后缀的变量是示例代码中声明的成员域:

// 获得名称空间
using msxml2;
...
// 创建对象
xmlhttp_ = new xmlhttp();

  为了连接到安全服务器,webdav协议要求执行http/1.1验证。httpmail客户程序发出的第一个请求利用webdav propfind方法查找一组属性,其中包括hotmail广告条的url以及信箱文件夹的位置:

<?xml version="1.0"?>
<d:propfind xmlns:d="dav:" xmlns:h="http://schemas.microsoft.com/hotmail/"
xmlns:hm="urn:schemas:httpmail:">
<d:prop>
<h:adbar/>
<hm:contacts/>
<hm:inbox/>
<hm:outbox/>
<hm:sendmsg/>
<hm:sentitems/>
<hm:deleteditems/>
<hm:drafts/>
<hm:msgfolderroot/>
<h:maxpoll/>
<h:sig/>
</d:prop>
</d:propfind>

通过xmlhttp发送第一个请求时,首先指定webdav服务器url,然后生成xml请求的内容:
// 指定服务器的url
string serverurl = "http://services.msn.com/svcs/hotmail/httpmail.asp";
// 构造查询
string folderquery = null;
folderquery += "<?xml version=1.0?><d:propfind xmlns:d=dav: ";
folderquery += "xmlns:h=http://schemas.microsoft.com/hotmail/ ";
folderquery += "xmlns:hm=urn:schemas:httpmail:><d:prop><h:adbar/>";
folderquery += "<hm:contacts/><hm:inbox/><hm:outbox/><hm:sendmsg/>";
folderquery += "<hm:sentitems/><hm:deleteditems/><hm:drafts/>";
folderquery += "<hm:msgfolderroot/><h:maxpoll/><h:sig/></d:prop></d:propfind>";

  xmlhttp组件提供了一个open()方法来建立与http服务器的连接:
void open(string method, string url, bool async, string user, string password);

  open()方法的第一个参数指定了用来打开连接的http方法,例如get、post、put或propfind,通过这些http方法我们可以提取文件夹信息、收集邮件或发送新邮件。为连接到hotmail网关,我们指定用propfind方法来查询信箱。注意open()方法允许执行异步调用(默认启用),对于带图形用户界面的邮件客户程序来说,异步调用是最理想的调用方式。由于本文的示例程序是一个控制台应用,我们把这个参数设置成false。

  为了执行身份验证,我们在open()方法中指定了用户名字和密码。在使用xmlhttp组件时,如果open()方法没有提供用户名字和密码参数,但网站要求执行身份验证,xmlhttp将显示出一个登录窗口。为了打开通向hotmail网关的连接,我们把propfind请求的头设置成xml查询的内容,消息的正文保持空白,然后发送消息:

// 打开一个通向hotmail服务器的连接
xmlhttp_.open("propfind", serverurl, false, username, password);
// 发送请求
xmlhttp_.setrequestheader("propfind", folderquery);
xmlhttp_.send(null);

  二、分析信箱的文件夹列表

  发送给services.msn.com的请求通常要经历几次重定向,经过服务器端的负载平衡处理,最后请求会被传递到一个空闲的hotmail服务器,并执行身份验证。在客户端,这个重定向、执行身份验证的交互过程由xmlhttp组件负责处理。成功建立连接后,服务器还会要求设置一些cookie、验证当前会话的合法性,这部分工作同样也由xmlhttp组件自动处理。初始的连接请求发出之后,服务器将返回一个xml格式的应答:

// 获得应答的内容
string folderlist = xmlhttp_.responsetext;



  服务器返回的应答包含许多有用的信息,其中包括信箱中文件夹的url位置,下面是一个例子:

<?xml version="1.0" encoding="windows-1252"?>
<d:response>
...
<d:propstat>
<d:prop>
<h:adbar>adpane=off*...</h:adbar>
<hm:contacts>http://law15.oe.hotmail.com/...</hm:contacts>
<hm:inbox>http://law15.oe.hotmail.com/...</hm:inbox>
<hm:sendmsg>http://law15.oe.hotmail.com/...</hm:sendmsg>
<hm:sentitems>http://law15.oe.hotmail.com/...</hm:sentitems>
<hm:deleteditems>http://law15.oe.hotmail.com/...</hm:deleteditems>
<hm:msgfolderroot>http://law15.oe.hotmail.com/...</hm:msgfolderroot>
...
</d:prop>
</d:response>
</d:multistatus>



  在本文的控制台示例程序中,我们感兴趣的两个文件夹是收件箱和发件箱的文件夹,它们分别用于接收和发送邮件。

  在c#环境中解析xml的方法很多,由于我们肯定代码涉及的所有xml文档总是合法的,所以可以利用system.xml.xmltextreader速度快的优势。xmltextreader是一个“只向前”的读取器,下面把xml字符数据转换成字符流,初始化xml读取器:

// 初始化
inboxurl_ = null;
sendurl_ = null;
// 装入xml
stringreader reader = new stringreader(folderlist);
xmltextreader xml = new xmltextreader(reader);



  遍历各个节点,选取出hm:inbox和hm:sendmsg节点,这两个节点分别代表收件箱和发件箱:

// 读取xml数据
while(xml.read())
{
// 是一个xml元素?
if(xml.nodetype == xmlnodetype.element)
{
// 获取该节点
string name = xml.name;
// 该节点代表收件箱?
if(name == "hm:inbox")
{
// 保存收件箱url
xml.read();
inboxurl_ = xml.value;
}
// 该节点代表发件箱?
if(name == "hm:sendmsg")
{
// 保存发件箱url
xml.read();
sendurl_ = xml.value;
}
}
}



  只有先获取当前这次会话的合法的收件箱和发件箱url,才可以发送和接收邮件。

  三、列举文件夹内容

  得到了信箱文件夹(如收件箱)的url之后,就可以向该文件夹的url发送webdav请求列举其内容。示例程序定义了一个托管类型mailitem,用来保存文件夹里一项内容(即一个邮件)的信息。文件夹内容列举从初始化一个mailitems数组开始:

// 初始化
arraylist mailitems = new arraylist();



  为获得邮件主题、收件人地址、发件人地址之类的邮件基本信息,我们要用到下面xml格式的webdav查询:

<?xml version="1.0"?>
<d:propfind xmlns:d="dav:" xmlns:hm="urn:schemas:httpmail:" xmlns:m="
   urn:schemas:mailheader:">
<d:prop>
<d:isfolder/>
<hm:read/>
<m:hasattachment/>
<m:to/>
<m:from/>
<m:subject/>
<m:date/>
<d:getcontentlength/>
</d:prop>
</d:propfind>



  生成上述xml查询字符串的c#代码:

// 构造查询
string getmailquery = null;
getmailquery += "<?xml version=1.0?><d:propfind xmlns:d=dav: ";
getmailquery += "xmlns:hm=urn:schemas:httpmail: ";
getmailquery += "xmlns:m=urn:schemas:mailheader:><d:prop><d:isfolder/>";
getmailquery += "<hm:read/><m:hasattachment/><m:to/><m:from/><m:subject/>";
getmailquery += "<m:date/><d:getcontentlength/></d:prop></d:propfind>";



  就象前面获取信箱文件夹清单的方式一样,上述请求也通过xmlhttp用propfind方法发送,这次我们把请求的正文设置成查询字符串。由于当前会话的用户身份已经通过验证,所以xmlhttp open()调用中不必再提供用户名字和密码:

// 获取邮件信息
xmlhttp_.open("propfind", folderurl, false, null, null);
xmlhttp_.send(getmailquery);
string folderinfo = xmlhttp_.responsetext;



  如果请求成功,服务器返回的应答xml流包含了该文件夹中各个邮件的信息:

<d:multistatus>
<d:response>
<d:href>
http://sea1.oe.hotmail.com/cgi-bin/hmdata/...
</d:href>
<d:propstat>
<d:prop>
<hm:read>1</hm:read>
<m:to/>
<m:from>mark anderson</m:from>
<m:subject>re: new information</m:subject>
<m:date>2002-08-06t16:38:39</m:date>
<d:getcontentlength>1238</d:getcontentlength>
</d:prop>
<d:status>http/1.1 200 ok</d:status>
</d:propstat>
</d:response>
...



  观察服务器返回的应答,我们发现每一个节点包含一组标识邮件的域,例如通过标记可提取出邮件。下面我们再次使用system.xml.xmltextreader解析这个xml数据流,首先初始化流读取器:

mailitem mailitem = null;

// 装入xml
stringreader reader = new stringreader(folderinfo);
xmltextreader xml = new xmltextreader(reader);



  四、分析邮件基本信息

  为了遍历一次就解析好整个xml文档,我们在每次打开元素时就创建一个新的mailitem实例,一遇到标记的末尾就保存该实例,在此期间,我们提取并设置mailitem的域:

// 读取xml数据
while(xml.read())
{
string name = xml.name;
xmlnodetype nodetype = xml.nodetype;
// 是一个email?
if(name == "d:response")
{
// 开始?
if(nodetype == xmlnodetype.element)
{
// 创建一个新的mailitem
mailitem = new mailitem();
}
// 结束?
if(nodetype == xmlnodetype.endelement)
{
// 保存email
mailitems.add(mailitem);
// 清除变量
mailitem = null;
}
}

// 是一个元素?
if(nodetype == xmlnodetype.element)
{
// 邮件的url属性
if(name == "d:href")
{
// 继续读取
xml.read();
mailitem.url = xml.value;
}

// 邮件的“已阅读”属性
if(name == "hm:read")
{
// 继续读取
xml.read();
mailitem.isread = (xml.value == "1");
}

// 其他mailitem的属性...
}
}



  上面的代码枚举指定文件夹内的每一个mailitem,分别提取各个mailitem的下列属性:

xml节点 说明
d:href 用来提取邮件的url
hm:read 如果邮件已阅读,则该标记被设置
m:to 收件人
m:from 发件人
m:subject 邮件主题
m:date 时间标记
d:getcontentlength 邮件的大小(字节数)



  五、接收邮件

  枚举出文件夹里面的mailitem之后,我们就可以利用mailitem的url获得邮件本身,只需要向hotmail服务器发送一个http/1.1 get请求就可以了。示例代码中的loadmail()函数输入一个mailitem实例作为参数,返回邮件的内容:

/// <summary>
/// 下载mailitem指定的邮件
/// </summary>
public string loadmail(mailitem mailitem)
{
// 邮件的url
string mailurl = mailitem.url;
// 打开hotmail服务器连接
xmlhttp_.open("get", mailurl, false, null, null);
// 发送请求
xmlhttp_.send(null);
// 获取应答
string maildata = xmlhttp_.responsetext;
// 返回邮件数据
return maildata;
}



  六、发送邮件

  loadmail()方法通过发送http/1.1 get请求获取邮件,类似地,用hotmail发件箱发送邮件时我们提交一个post请求,如下面的sendmail()方法所示。

/// <summary>
/// 发送一个邮件
/// </summary>
public void sendmail(string from, string fromname,
string to, string subject, string body)
{
...
}



  首先准备好后面要用到的引号字符以及邮件的时间标记:

// 引号字符
string quote = "\u0022";

// 时间标记
datetime now = datetime.now;
string timestamp = now.tostring("ddd, dd mmm yyyy hh:mm:ss");



  httpmail协议采用与smtp相似的通信模式。outlook express用mime格式发送邮件,但为简单计,本例我们只发送纯文本的邮件:

// 构造post请求的内容
string postbody = null;
// 邮件头.
postbody += "mail from:<" + from + ">\r\n";
postbody += "rcpt to:<" + to + ">\r\n";
postbody += "\r\n";
postbody += "from: " + quote + fromname + quote + " <" + from + ">\r\n";
postbody += "to: <" + to + ">\r\n";
postbody += "subject: " + subject +"\r\n";
postbody += "date: " + timestamp + " -0000\n";
postbody += "\r\n";
// 邮件正文
postbody += body;



  发送邮件时,我们要把content-type请求头设置成message/rfc821,表示这个请求包含一个遵从rfc821的消息。最后要做的就是把邮件发送到服务器:

// 打开连接
xmlhttp_.open("post", sendurl_, false, null, null);
// 发送请求
xmlhttp_.setrequestheader("content-type", "message/rfc821");
xmlhttp_.send(postbody);



  只要目标地址正确无误,hotmail就会把邮件发送到目的地。

  结束语:

  hotmail是世界上最大的免费web邮件提供商。但是,hotmail使用的httpmail协议是非公开的,从而为编写直接访问hotmail的客户程序带来了困难。本文示范了如何在c#环境中利用xmlhttp组件直接连接到hotmail,以及如何发送和接收邮件,证明了通过httpmail连接hotmail可以做到象使用pop3、imap4、smtp等协议一样简单。

代码下载地址:http://www.webasp.net/tech/download_show.asp?id=377

文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·使用C#编写Windows Forms应用程序(转)-.NET教程,Windows开发
·C#学习杂记-.NET教程,C#语言
·将文本格式的文章转换为html/xml格式文本的功能封装到Javabean-JSP教程,Java技巧及代码
·用java小程序applet实现无限级树结构-JSP教程,Java技巧及代码
·《.net编程先锋C#》第一章 C#简介-.NET教程,C#语言
·企业人事信息管理系统1.0-ASP教程,数据库相关
·《.net编程先锋C#》第三章 第一个C#应用程序-.NET教程,C#语言
·《.net编程先锋C#》第二章 理论基础-公用语言 运行环境-.NET教程,C#语言
·Windows应用程序调试必备的--符号文件(Symbols)-.NET教程,评论及其它
·c#反编译微软msdn2003的帮助文档,并将反编译结果保存到一个sqlserver数据库中
最新文章
·vista的新特性:懒人的安全感_windows vista
·photoshop为情侣照片打造韩式梦幻相框_photoshop教程
·专访seobbs站长乐思蜀_站长访谈
·嘟嘟网络陈艺光:诚信是一种信仰_站长访谈
·俺自己黄修源:只问耕耘,不问收获_站长访谈
·李向华:如何提高论坛用户粘性_站长访谈
·给windows vista系统网络和共享中心“换脸”_windows vista
·胡宪东谈搜索优化的实战_站长心得
·网站快速成功的九个步骤_站长心得
·google pr数字背后的含意_google推广
相关主题
  • 用c#访问access数据库问题_c#应用
  • 用C#访问Access数据库-.NET教程,数据库应用
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭