.NET Data Access Class for Exchange 2000 Webstore
使用 WEBDAV 访问 Exchange 2000 Webstore 数据的 VB.NET 程序集。
重要更新
之前在线提供在 webservices.bus.oregonstate.edu 上的 XSLT 文件将不再可用。您需要下载它们,并按照下面“更新”部分中的说明进行更改。请**查看更新部分**!
引言
ExDAV 程序集是一组用于查询和创作 Microsoft Exchange 2000 Webstore 数据的类。这通过类内部使用 WebDAV 与存储进行通信来实现。这些类封装了所有通信,因此使用这些类的程序员不必手动实现 WebDAV 调用。该程序集提供了使用 Exchange 2000 的“SEARCH”动词进行类似 SQL 的搜索的功能,以及标准的 WebDAV 动词,如“PROPFIND”。搜索结果可以以原始 XML、XML.NET XML 文档、ADO.NET DataSet
的形式返回,并且在“PROPFIND”的情况下,可以返回一个包含在程序集中的递归对象。在创作方面,该程序集提供了写入属性、创建项和集合、复制、移动和删除的功能。
背景
创建此对象是因为我们需要从我们的 .NET 应用程序访问 Exchange 2000 Webstore 数据。我们的目的是创建一组类,使我们能够处理 Exchange 数据,而无需进行任何繁琐的 COM 组件封装。
使用代码
要使用该程序集,有三个类最为重要:ExSearcher
、ExModifier
和 ExResponse
。ExSearcher
类用于查询 Exchange 存储,并有两个方法用于此操作:Search
和 Find
。Search
方法接受一个 string
参数 sWhere
,该参数是一个 SQL WHERE
子句,用于过滤搜索结果。发送到 Exchange 存储的请求以 SQL 格式进行(代码片段为 C#)。
ExDAV.ExSearcher searcher = new
ExDav.ExSearcher("http://mystore.edu/myresource");
searcher.Depth = ExDAV.ExRequest.ExRequestDepths.AllChildrenWithRoot;
searcher.ExProps.Add("DAV:", "creationdate");
ExDAV.ExResponse resp = searcher.Search("WHERE \"DAV:isfolder\" = true");
...
我稍后会介绍 ExResponse
类。
重要提示:对于 ExSearcher
和 ExModifier
,要检索或修改的属性必须添加到 ExProps
集合中,这是一个 ExProperty
对象集合。属性使用 URN、本地名称指定,在更新的情况下还包括值。下面的代码显示了如何设置 DAV:creationdate
属性以在我们的搜索器中检索(URN = 'DAV:'
,Local Name = 'creationdate'
)。
...
searcher.ExProps.Add("DAV:", "creationdate");
...
Find
方法执行类似的功能,但没有 SQL WHERE
子句过滤器。发送到 Exchange 存储的请求是一个典型的“PROPFIND”WebDAV 调用(这里我们也需要将我们要“查找”的属性添加到 ExProps
集合中)。
ExDAV.ExSearcher searcher = new
ExDav.ExSearcher("http://mystore.edu/myresource");
searcher.Depth = ExDAV.ExRequest.ExRequestDepths.AllChildrenWithRoot;
//Add the properties to look for
searcher.ExProps.Add("DAV:", "creationdate");
ExDAV.ExResponse resp = searcher.Find();
...
现在回到 ExResponse
类。此类用于提取服务器的响应。ExResponse
类有几种方法可以以不同方式返回结果。ResponseXML
属性可用于检索 Exchange 存储返回的原始 XML。
...
string sRawXML = resp.ResponseXML;
...
其他方法允许将响应分析为 System.Xml.XmlDocument
、System.Data.DataSet
或 ExDAV.ExObject
。(**重要**:ExObject
只能用于 ExDAV.Searcher.Find()
方法的响应。)
...
System.Data.DataSet ds = resp.GetDataSet("dsMyExDataSet",
"dsMyExTableName");
...
提示:ExResponse
类的 GetDatasetSchemaXMLReader
方法返回一个 System.IO.StringReader
,其中包含 GetDataSet
方法返回的 DataSet
的架构。这允许程序员保存架构,甚至创建强类型数据集架构文件,以绑定控件。
ExModifier
类用于在 Exchange 存储上进行创作。创作方法包括:CreateNewItem
、CreateFolder
、CopyTo
、MoveTo
、Update
和 Delete
。这些方法不言自明。
ExDAV.ExModifier modifier = new
ExDav.ExModifier("http://mystore.edu/myitem.eml");
modifier.Depth = ExDAV.ExRequest.ExRequestDepths.NullDepth;
//set up the credential
modifier.Credential = new System.Net.NetworkCredential("myUserName",
"myPassword", "myDomain");
//add the property to update
modifier.ExProps.Add("DAV:", "displayname", "MyItemNewName");
ExDAV.ExResponse resp = modifier.Update(true,
ExDAV.ExModifier.ModifierFlags.AddIfNotExistsOverwriteIfExists);
...
返回的 ExResponse
对象上的 StatCode
和 StatDesc
属性可用于分析请求的成功情况。
有关如何使用程序集的更多信息,请参阅源代码中的注释和演示项目。
幕后
我收到了一些关于讨论程序集中 WebDAV 实现以及我们检索结果方法的请求,所以有兴趣的人可以继续。ExSearcher
和 ExModifier
都继承自 ExRequest
类。此类包含实际 WebDAV 请求的实现以及 ExProps
等公共属性。进行 WebDAV 调用的方法是 GetDAVResponse
,它接收编码为字节数组的请求 XML 正文和一个预打包的 System.Net.WebRequest
(代码用 VB.NET 编写)。
'GetDAVResponse is the main method of the whole assembly.
'This is where we actually communicate with the Exchange Store.
Friend Function GetDAVResponse(ByVal arrData() As Byte, _
ByVal HTTPRequest As WebRequest) As ExResponse
Dim oResponse As WebResponse
Dim oStreamIn As Stream
Dim oHTTPResp As HttpWebResponse
Dim oResponseXML As New XmlDocument()
Dim oStreamRead As StreamReader
Dim sResp As String
Dim oExResp As ExResponse
Dim sCode As String = ""
Dim sDesc As String = ""
Dim oStream As Stream
Try
'If body data has been submitted add it to the request stream
If Not arrData Is Nothing Then
Dim oStreamOut As Stream = HTTPRequest.GetRequestStream()
oStreamOut.Write(arrData, 0, arrData.Length)
oStreamOut.Close()
End If
'This is where the request is sent and the response recieved
oResponse = HTTPRequest.GetResponse()
'Use an HTTPWebResponse object so we can get more info
oHTTPResp = oResponse
'Get the Response stream and read it into a string
oStreamIn = oResponse.GetResponseStream()
oStreamRead = New StreamReader(oStreamIn)
sResp = oStreamRead.ReadToEnd()
'Some requests have no resulting response bodies so set a default one
If sResp ="" Then
sResp = "<?xml version=""1.0""?><NoResponse></NoResponse>"
End If
'Set up the ExResponse
object that we will be returning
oExResp = New ExResponse(m_URI, sResp, oHTTPResp.StatusCode, _
oHTTPResp.StatusDescription, oHTTPResp)
Catch myWebEx As WebException
'This is where we will end up if the server
'the resource is on returns an error
'So we setup an ExDavException to throw.
oHTTPResp = myWebEx.Response
If Not oHTTPResp Is Nothing Then
sCode = oHTTPResp.StatusCode
sDesc = oHTTPResp.StatusDescription
End If
sResp = "<?xml version=""1.0"" ?><" & _
"EXDAVError type=""WebRequest Error""><Code>" & _
sCode & "</Code><Description>" & _
sDesc & "</Description><Message>" & _
myWebEx.Message & "</Message></EXDAVError>"
Dim sMsg as String = "There was an error _
processing the web request." & _
"See the ErrXML property for more details."
oExResp = New ExResponse(m_URI, sResp, sCode, sDesc, oHTTPResp)
Throw New ExDAVException(m_URI, sMsg, sResp, oHTTPResp)
Catch myEx As Exception
'Any other exception puts us in here,
'so throw a generic ExDavException
Dim sMsg as String = "There was an error processing _
the web request." & _
"See the ErrXML property _
for more details."
Throw New ExDAVException(m_URI, sMsg, sResp)
End Try
'Return the response
GetDAVResponse = oExResp
End Function
在 .NET 中使用 WebDAV 调用时,主要使用两个类:System.Net.WebRequest
类和 System.Net.WebResponse
。还有另外两个类继承自这些类:System.Net.HttpWebRequest
和 System.Net.HttpWebResponse
,它们具有使用 HTTP 协议的额外功能。此方法中的 WebRequest
是预打包的,并如前所述作为参数传入,以及 XML 正文内容。以下是创建和设置 WebRequest
以及 XML 正文内容的示例代码。
'Instantiate the web request
Dim oHTTP As WebRequest = CType(WebRequest.Create(MyBase.uURI.ToString),
WebRequest)
'Encode the body and get the bytes.
'The body contains XML in the standard WebDAV schema.
Dim bytes() As Byte = Encoding.ASCII.GetBytes(sXML)
'Build the request and its headers
oHTTP.Credentials = MyBase.Credential
oHTTP.ContentType = "text/xml"
oHTTP.ContentLength = bytes.Length
oHTTP.Method = "PROPFIND"
oHTTP.Headers.Add("Depth", sDepth)
oHTTP.Headers.Add("Brief", "t")
这真的就是全部了:创建一个 WebRequest
,将 WebDAV XML 内容写入 WebRequest
的请求流,然后使用 WebRequest
的 GetResponse
方法进行调用并获取响应。最后,使用 WebResponse
的 GetResponseStream
方法检索服务器发送的 XML 响应。
为了将服务器的原始 XML 转换为对象模型或 ADO.NET DataSet
,我们使用 XSLT 转换。此转换将原始 XML 转换为可反序列化为对象或读入 DataSet
的架构。有关详细信息,请参阅 ExResponse
类下的源代码。如果涉及大量数据,此方法会存在明显的性能问题,我很想听听有关更好方法的建议。然而,我们发现,将数据作为递归对象或 DataSet
访问比作为原始 XML 更有用。
更新
随着变化的发生,我将在此发布。
- 2005 年 8 月 2 日 - 正如最后一段所述,
ExObject
和 ADO.NETDataSet
s 需要 XSLT 转换。这些 XSLT 样式表可以在 ExTransform.xslt 和 DsTransform.xslt 找到。这些样式表**将不再在代码中指定的链接可用**。请下载这些样式表并将它们保存在 Web 服务器上,然后更改第 1361 行和第 1433 行以反映这些样式表的新位置。或者,您可以下载它们并将它们嵌入为资源。这将需要对代码进行更多修改,但消除了对样式表在线可用的依赖。讨论中有如何执行此操作的说明。