65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2009年1月26日

CPOL

4分钟阅读

viewsIcon

69179

downloadIcon

593

演示了通过 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 文档。是的,这是我整理的一个文档。我从同事那里得到的文档并不那么整洁。

Excel_Doc.png

这里有五个文件需要上传。它们具有元数据字段 TitleRegion,并且每个文件都需要放置到其相应的区域文件夹中。我们就假设我们的公司有不同的分支机构,他们希望将他们的文档放在自己的文件夹中,这样就不会与其他分支机构的文档混淆。

我创建了一个启用了文件夹功能的文档库,并且添加了 Region 列。下面的图片是该库的默认视图。

List.png

好的,现在我已经创建了该库,让我们开始运行 SPExcelImport

Import_Excel.png

在 SharePoint 设置中,您需要输入要连接到的站点的 URL。请记住,Web 服务是根据您用来连接它们的 URL 来工作的。如果您想获取子站列表中列表的信息,则需要输入该子站的完整路径。例如,http(s)://<yourserver>/<sitecollection>/<subsite>。输入后,您可以单击“Go”。当您单击“Go”时,所有列表架构都将通过 Web 服务检索回来,您将获得一个列表供您在下拉列表中选择。让我们看看当单击“Go”按钮时代码中发生了什么。

首先,我们将创建一个 SPRepositoryProviderSPRepositoryRequest 实例。

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

Column_Selector.png

一旦您有了 SPColumn 对象,您就可以访问以下所有属性:

SPColumn.png

所有这些信息对于索引目的都非常有用。例如,确保您的用户输入有效数据。

配置好映射后,您可以单击“Start”。

单击“Start”按钮时,我们将启动一个新线程来处理。它将遍历 Excel 文件中的每一行,检索我们的元数据值并上传我们的文档。这一切都可以通过之前检索到的 SPList 对象轻松完成。概述一下,让我们看看 SPList 对象的所有属性和方法。

SPList.png

您可以看到,有很多信息可以帮助到您。好的,让我们看看一些使用 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;

    }
}

List_Root_Folder.png

文档上传完成后,我们将看到我们的 Test 文件夹。单击它,您将看到:

List_Test_Folder.png

现在,我们可以单击我们的 Mid West 文件夹并查看我们的文档。

List_Mid-west_folder.png

结论

我在将项目导入 SharePoint 方面做了很多工作,希望这个库能为您节省时间。如果您有任何疑问,请随时提出。如果您使用此代码生成任何导入 SharePoint 的应用程序,我只希望您将其发布并分享。

© . All rights reserved.