使用 Web 服务和 RPC 远程获取列表架构并导入列表项/文档到 SharePoint





5.00/5 (7投票s)
演示了通过 Web 服务和 RPC 检索架构并导入到 SharePoint。
引言
随着 SharePoint 的日益普及,许多人都在构建应用程序来索引和上传他们的文档到 SharePoint。使用对象模型上传文档很容易理解,但是如果您想构建一个需要从客户端机器上传的应用程序呢?我在这里将您一半的时间都节省了下来,构建了一个库,可以帮助您检索 SharePoint 架构并上传您的文档,同时还支持文件夹功能。现在,您只需编写生成文档及其相关元数据的代码。出于学习目的,我创建了一个示例应用程序,该应用程序连接到 Excel 2003 文档并上传其中的引用文档。
背景
SharePoint 提供了大量的 Web 服务,但我们将要使用的是 Lists.asmx。此 Web 服务可以通过 http(s)://<yourserver>/<site|subsite>/_vti_bin/lists.asmx 访问。此服务可以检索架构、上传、删除和修改文档。
Using the Code
正如我之前所说,我创建了一个示例应用程序,用于上传 Excel 2003 文档中引用的文档。此应用程序还将项目上传到不引用文档的列表中。那么,让我们来看看我的 Excel 2003 文档。是的,这是我整理的一个文档。我从同事那里得到的文档并不那么整洁。
这里有五个文件需要上传。它们具有元数据字段 Title
和 Region
,并且每个文件都需要放置到其相应的区域文件夹中。我们就假设我们的公司有不同的分支机构,他们希望将他们的文档放在自己的文件夹中,这样就不会与其他分支机构的文档混淆。
我创建了一个启用了文件夹功能的文档库,并且添加了 Region 列。下面的图片是该库的默认视图。
好的,现在我已经创建了该库,让我们开始运行 SPExcelImport。
在 SharePoint 设置中,您需要输入要连接到的站点的 URL。请记住,Web 服务是根据您用来连接它们的 URL 来工作的。如果您想获取子站列表中列表的信息,则需要输入该子站的完整路径。例如,http(s)://<yourserver>/<sitecollection>/<subsite>。输入后,您可以单击“Go”。当您单击“Go”时,所有列表架构都将通过 Web 服务检索回来,您将获得一个列表供您在下拉列表中选择。让我们看看当单击“Go”按钮时代码中发生了什么。
首先,我们将创建一个 SPRepositoryProvider
和 SPRepositoryRequest
实例。
SPRepositoryProvider provider = new SPRepositoryProvider();
SPRepositoryRequest request = new SPRepositoryRequest();
request.Uri = tboxSharePointUrl.Text;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
现在,我们可以继续调用检索 SPRepository
对象的方法。此对象包含一个集合 Lists
。然后,我们可以循环遍历这些列表并将它们填充到我们的库组合框中。
SPRepository repository = provider.GetRepository(_spRequest).Repository;
foreach (SPList lib in spRepository.Lists.Values)
cboLibrary.Items.Add(lib);
一旦用户选择了他们的库,我们将要填充内容类型组合框,以便他们可以选择要使用哪一个。
foreach (SPContentType contentType in lib.ContentTypes.Values)
cboContentType.Items.Add(contentType);
在 SPContentType
对象中,您可以访问所有列。选择 Excel 文件后,您将能够映射您的列。然后,表单将 SPColumn
集合绑定到 DataGrid
。
一旦您有了 SPColumn
对象,您就可以访问以下所有属性:
所有这些信息对于索引目的都非常有用。例如,确保您的用户输入有效数据。
配置好映射后,您可以单击“Start”。
单击“Start”按钮时,我们将启动一个新线程来处理。它将遍历 Excel 文件中的每一行,检索我们的元数据值并上传我们的文档。这一切都可以通过之前检索到的 SPList
对象轻松完成。概述一下,让我们看看 SPList
对象的所有属性和方法。
您可以看到,有很多信息可以帮助到您。好的,让我们看看一些使用 SPList
的实际代码。
在 ExecuteProcess
中,我们将遍历 Excel 文档中的每一行,并使用 SPList.CreateNewItem(SPContentType)
从 SPList
创建一个 SPItem
。此方法将返回一个 SPItem
,其所有属性都从架构中默认设置。然后,我们将设置其 Folder、Properties 和 Binary 属性。然后,我们可以更新该项,就完成了。文档现在就在 SharePoint 中了。如果我们不想签入文档,可以将 SPUpdateItemRequest
对象的 CheckIn
属性设置为 false
。
private void ExcecuteProcess()
{
try
{
DataTable dsItems = GetItems();
_rwlStat.AcquireWriterLock(Timeout.Infinite);
_processedItemsCount = 0;
_erroredItemsCount = 0;
_totalItemsCount = 0;
_totalItemsCount = dsItems.Rows.Count;
if (_rwlStat.IsWriterLockHeld)
_rwlStat.ReleaseWriterLock();
foreach (DataRow dr in dsItems.Rows)
{
try
{
if (_isStop)
return;
SPList list = _context.ContentType.List;
SPItem item = list.CreateNewItem(_context.ContentType);
SetFields(item, dr);
SetFolder(item, dr);
if (item.ContentType.List.BaseType == SPListBaseType.DocumentLibrary)
SetBinary(item, dr);
list.UpdateItem(new SPUpdateItemRequest() { Item = item });
_rwlStat.AcquireWriterLock(Timeout.Infinite);
_processedItemsCount++;
ProcessStatusInfo psi = new ProcessStatusInfo();
psi.ErroredItemsCount = _erroredItemsCount;
psi.ProcessedItemsCount = _processedItemsCount;
psi.TotalItemsCount = _totalItemsCount;
if (_rwlStat.IsWriterLockHeld)
_rwlStat.ReleaseWriterLock();
_context.SyncContext.Post(_context.UpdateStatusCallback, psi);
}
catch (Exception ex)
{
_rwlStat.AcquireWriterLock(Timeout.Infinite);
_erroredItemsCount++;
if (_rwlStat.IsWriterLockHeld)
_rwlStat.ReleaseWriterLock();
ProcessStatusInfo psi = new ProcessStatusInfo();
psi.ErroredItemsCount = _erroredItemsCount;
psi.ProcessedItemsCount = _processedItemsCount;
psi.TotalItemsCount = _totalItemsCount;
_context.SyncContext.Post(_context.UpdateStatusCallback, psi);
UpdaterLog.LogException(ex);
}
}
}
catch (Exception ex)
{
Logging.UpdaterLog.LogException(ex);
_isFaulted = true;
}
finally
{
ProcessStatusInfo psi = new ProcessStatusInfo();
psi.Finished = true;
psi.ErroredItemsCount = _erroredItemsCount;
psi.ProcessedItemsCount = _processedItemsCount;
psi.TotalItemsCount = _totalItemsCount;
_context.SyncContext.Post(_context.UpdateStatusCallback, psi);
}
}
private void SetFolder(SPItem item, DataRow dr)
{
if (_context.FolderColumn == null)
return;
string folder = dr[_context.FolderColumn.Name].ToString();
item.Folder = folder.Trim('/', '\\').Replace('\\','/');
}
private void SetBinary(SPItem item, DataRow dr)
{
if (_context.FileColumn == null)
throw new Exception("File Field is not set.");
FileInfo fi = new FileInfo(dr[_context.FileColumn.Name].ToString());
if (!fi.Exists)
throw new Exception(string.Format("File '{0}' could not be found.",
fi.FullName));
item.Name = Path.GetFileNameWithoutExtension(fi.Name);
item.Extension = fi.Extension.Trim('.');
item.Binary = File.ReadAllBytes(fi.FullName);
}
private void SetFields(SPItem item, DataRow dr)
{
foreach (ColumnMapping cm in _context.ColumnMapping)
{
SPColumn col = item.ContentType.Columns[cm.SPColumn];
if (item.Properties.ContainsKey(col.Name))
item.Properties[col.Name] = dr[cm.ExColumn].ToString();
}
}
private DataTable GetItems()
{
StringBuilder sbCols = new StringBuilder();
List<string> selectColumns = new List<string>();
for (int i = 0; i < _context.ColumnMapping.Count; i++)
{
string excelColName = _context.ColumnMapping[i].ExColumn;
if(selectColumns.Contains(excelColName.ToLower()))
continue;
else
selectColumns.Add(excelColName.ToLower());
if (i != 0)
sbCols.Append(", ");
sbCols.Append("[");
sbCols.Append(excelColName);
sbCols.Append("]");
}
if (_context.FileColumn != null &&
!selectColumns.Contains(_context.FileColumn.Name.ToLower()))
{
if (sbCols.Length != 0)
sbCols.Append(", ");
sbCols.Append("[");
sbCols.Append(_context.FileColumn.Name);
sbCols.Append("]");
selectColumns.Add(_context.FileColumn.Name);
}
if (_context.FolderColumn != null &&
!selectColumns.Contains(_context.FolderColumn.Name.ToLower()))
{
if (sbCols.Length != 0)
sbCols.Append(", ");
sbCols.Append("[");
sbCols.Append(_context.FolderColumn.Name);
sbCols.Append("]");
selectColumns.Add(_context.FolderColumn.Name);
}
using (OleDbConnection conn =
new OleDbConnection(_context.ExDatabaseRequest.ConnectionString))
{
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
cmd.CommandText = string.Format(@"SELECT {0} FROM [{1}]",
sbCols.ToString(), _context.Table.QueryName);
OleDbDataAdapter oleDataAdapter = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
oleDataAdapter.Fill(dt);
return dt;
}
}
文档上传完成后,我们将看到我们的 Test 文件夹。单击它,您将看到:
现在,我们可以单击我们的 Mid West 文件夹并查看我们的文档。
结论
我在将项目导入 SharePoint 方面做了很多工作,希望这个库能为您节省时间。如果您有任何疑问,请随时提出。如果您使用此代码生成任何导入 SharePoint 的应用程序,我只希望您将其发布并分享。