将文件上传到 SharePoint 文档库并更新任何元数据列






4.41/5 (15投票s)
如何将文件上传到 SharePoint 文档库并更新任何元数据列。
引言
本文描述了按顺序将文件上传到 SharePoint 文档库,然后使用 CAML 更新每个文件的自定义元数据。本文还描述了如何使用 DWS Web Service 在文档库中创建文件夹/子文件夹,以及如何使用 List Web Service 在文档库中上传/更新文件。
背景
在我的组织中,每天都会扫描大量文档(*.pdf),我们维护一个复杂的电子文档审批系统,并根据相应的元数据进行过滤/搜索。文件命名方式很具体。我必须用 VB.NET 编写一个名为 File Shunter 的 Web Service,其中包含两个函数:一个函数接收输入文件夹并将文件上传到服务器上的特定文件夹(此函数还使用 SharePoint DWS Web service 根据文件名中的规则创建文件夹/子文件夹),以及另一个函数,针对正在上传的每个文档,从文件名中提取所有必需的元数据,并在文件上传后,使用 CAML 和 List Web service (http://sp portal/subsite/_vti_bin/lists.asmx) 来更新文件的必需元数据列。我使用 Web.config 来存储/检索文档库名称、门户名称、用户身份验证等……此代码使用 Web services,因此无需将代码运行在门户运行的服务器上(在使用了 SharePoint Object Model 的情况下)。
另一项功能是我们必须维护每个文件的版本历史记录。由于一个文件可以上传多次,我们需要保留修订版本。为此,如果在文档库中启用了版本历史记录,并且在文件上传后更改了文件的元数据,它将成为一个新版本。当我们需要在不创建新版本的情况下访问和更新当前文件时,可以使用 bEnableVersion(True/False) 函数,该函数在上传文件时设置为 True,以便如果文件已存在,则会在文档库中生成一个版本。但是,在更新其元数据时,版本历史记录设置为 False(bEnableVersion(False))。文档库的另一个优点是**它可以作为文件系统中的映射驱动器(因为它是一个 Web 文件夹)**。我们的文档部门以前习惯于从共享文件夹访问文件。现在,文件上传到 SharePoint 后,我们只需为每个用户将文档库映射为共享文件夹,这样他们在使用/访问这些文件时就没有区别。只需在用户的 PC 上启用 WebClient 服务并映射文档库(http://portal/site/doclib)。
使用代码
有两个主要函数:UploadDocument 和 WSSUpdateFile。第一个函数传入本地文件名(在文件系统上)和远程文件名(将在文档库中使用)。文件上传后,另一个函数传入文件名和要更新的任何元数据列值。出于测试目的,我在测试文档库中创建了一个名为“TestCol”的列,并为其传递了“Test Value”。但是,此函数可以根据需要传递任意数量的元数据列值。只需在函数中的 XML 批处理中添加列名和值即可。**要更新文件属性,通常需要其 ID 来访问它(即使在文件夹内)。** 我使用 CAML 来访问最近上传的文件并获取其 ID,然后此 ID 用于 List Web Service 的 UpdateListItems 函数来更新文件的属性。
包含的函数是“CreateFolder”,可用于在文档库中创建任意数量的文件夹/子文件夹。大多数常见的必需值,如门户 URL、文档库名称、用户、密码、域、文件夹名称(文件所在的目录,用于上传)都已在 Web.config 中设置,以便于修改。主函数访问这些值以确定所需数据和身份验证。要上传文件,例如从 D:\Test 文件夹,在 web.config 中,在 globalsharedpath 键下,添加“<add key="GlobalSharedPath" value="D:\"/>"
”。只传入“D:\”,然后在程序运行时,在输入文件夹名称中只传入“Test”。需要记住的一点是,某些 SharePoint Web Services 是站点特定的,这意味着您需要引用确切的站点/子站点才能与其配合使用。例如,如果我在 http://portal/sitedirectory/site 下有一个子站点,那么 List Web Service 的引用应该是 http://portal/sitedirectory/site/_vti_bin/lists.asmx。
<configuration>
<appSettings>
<add key="SharePointServer" value=http://SP Portal/Site/>
<add key="DocLibrary" value="Doclib"/>
<add key="User" value="User"/>
<add key="Domain" value="Domain"/>
<add key="Pwd" value="Pwd"/>
<add key="GlobalSharedPath" value="D:\"/>
</appSettings>
Public Function UploadDocument(ByVal localFile As String, _
ByVal remoteFile As String) As String
'// Read in the local file
On Error GoTo handler
Dim r As Byte()
Dim Strm As System.IO.FileStream = New System.IO.FileStream(localFile, _
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim reader As System.IO.BinaryReader = New System.IO.BinaryReader(Strm)
Dim filecontents As Byte() = reader.ReadBytes(CInt(Strm.Length))
reader.Close()
Strm.Close()
Dim sSPURL As String = ConfigurationManager.AppSettings("SharePointServer")
Dim sDocLib As String = ConfigurationManager.AppSettings("DocLibrary")
Dim sUser As String = ConfigurationManager.AppSettings("User")
Dim sPwd As String = ConfigurationManager.AppSettings("Pwd")
Dim sDomain As String = ConfigurationManager.AppSettings("Domain")
Dim sRemoteFileURL As String
Dim NC As System.Net.NetworkCredential = _
New System.Net.NetworkCredential(sUser, sPwd, sDomain)
sRemoteFileURL = sSPURL & "/" & sDocLib & _
"/" & Trim(LTrim(RTrim(remoteFile)))
sRemoteFileURL = Replace(sRemoteFileURL, " ", "%20")
sRemoteFileURL = Replace(sRemoteFileURL, "\", "/")
Dim m_WC As WebClient = New WebClient
m_WC.Credentials = NC
r = m_WC.UploadData(sRemoteFileURL, "PUT", filecontents)
Return "TRUE"
Exit Function
handler:
Return Err.Description
End Function
Public Function WSSUpdateFile(ByVal sFileName As String, ByVal sSiteDoc As String, _
ByVal sTestCol As String) As String
Dim sUser As String = ConfigurationManager.AppSettings("User")
Dim sPwd As String = ConfigurationManager.AppSettings("Pwd")
Dim sDomain As String = ConfigurationManager.AppSettings("Domain")
Dim sFileIDinList As String
Dim strBatch As String = ""
sSiteDoc = Replace(sSiteDoc, "%20", " ")
sSiteDoc = Replace(sSiteDoc, "\", "/")
Dim sFinalFilePath As String
Dim sSPURL As String = ConfigurationManager.AppSettings("SharePointServer")
Dim sDocLib As String = ConfigurationManager.AppSettings("DocLibrary")
Try
Dim netAccess As System.Net.NetworkCredential = _
New System.Net.NetworkCredential(sUser, sPwd, sDomain)
Dim listService As New SPLists.Lists
listService.Url = sSPURL & "/_vti_bin/lists.asmx"
listService.Credentials = netAccess
sFileIDinList = sGetID(listService.Url, sDocLib, sFileName)
If sFileIDinList <> "" Then
sFinalFilePath = sSPURL & "/" & sDocLib & "/" & sFileName
'Now we have FileID so update the list
strBatch = "<Method ID='1' Cmd='Update'>" + _
"<Field Name = 'ID'>" & sFileIDinList & "</Field>" + _
"<Field Name = 'FileRef'>" & sFinalFilePath & "</Field>" + _
"<Field Name = 'TestCol'>" & sTestCol & "</Field>" + _
"</Method>"
Dim xmlDoc = New System.Xml.XmlDocument
Dim elBatch As System.Xml.XmlElement = xmlDoc.createelement("Batch")
elBatch.InnerXml = strBatch
Dim ndreturn As System.Xml.XmlNode = _
listService.UpdateListItems(sDocLib, elBatch)
End If
Return "TRUE"
Catch ex As Exception
Return ex.Message
End Try
End Function
Private Function sGetID(ByVal sURL As String, ByVal sListGUID As String, _
ByVal sFileName As String) As String
Dim sUser As String = ConfigurationManager.AppSettings("User")
Dim sPwd As String = ConfigurationManager.AppSettings("Pwd")
Dim sDomain As String = ConfigurationManager.AppSettings("Domain")
Dim netAccess As System.Net.NetworkCredential = _
New System.Net.NetworkCredential(sUser, sPwd, sDomain)
Dim L As New SPLists.Lists
L.Credentials = netAccess
L.Url = sURL
Dim xmldoc As XmlDocument = New XmlDocument
Dim query As XmlNode = xmldoc.CreateNode(XmlNodeType.Element, "Query", "")
query.InnerXml = "<OrderBy><FieldRef Name='Modified' " & _
"Ascending='False'></FieldRef></OrderBy>"""
Try
Dim caml As XmlNode = L.GetListItems(sListGUID, Nothing, query, _
Nothing, "1", Nothing)
Dim id As String = caml.ChildNodes(1).ChildNodes(1).Attributes("ows_ID").Value
Return id
Catch ex As Exception
Return ex.Message
End Try
End Function
关注点
- 使用 Web Services 而非 OM
- 在文档库中创建文件夹
- 启用/禁用版本历史记录