【问题标题】:access Sharepoint document library items from provider-hosted app从提供商托管的应用程序访问 Sharepoint 文档库项目
【发布时间】:2018-01-30 11:32:22
【问题描述】:

所以我正在尝试从 C# 中的 Sharepoint 文档库访问文件。我的应用程序是提供商托管的 Sharepoint 应用程序。我似乎可以访问图书馆,但不能访问图书馆的项目。

这是我在控制器中获取上下文的方法:

var spContext = SharePointContextProvider.Current.GetSharePointContext(System.Web.HttpContext.Current);
using (var clientContext = spContext?.CreateUserClientContextForSPHost())
{
    if (clientContext != null)
    {
        template.SetMergefields(clientContext);
    }
}

以及我如何尝试访问这些文件:

Web web = clientContext.Web;

List templateList = web.Lists.GetByTitle(libraryName);
clientContext.Load(templateList);
clientContext.ExecuteQuery();

var templateFiles = templateList.RootFolder.Files;
clientContext.Load(templateFiles);
clientContext.ExecuteQuery();

var templateListItems = templateList.GetItems(CamlQuery.CreateAllItemsQuery());
clientContext.Load(templateListItems);
clientContext.ExecuteQuery();

此时,templateList 的属性ItemCount = 8 与库中的文件数匹配。然而,templateFilestemplateListItems 都有 Count = 0,所以我似乎无法访问这 8 个项目。

我还尝试通过我在 Sharepoint 上查找的 id 访问单个项目:

var itemWithId1 = templateList.GetItemById(1);
clientContext.Load(itemWithId1);
clientContext.ExecuteQuery();

但这会导致错误:

Microsoft.SharePoint.Client.ServerException: '项目不存在。它可能已被其他用户删除。'

我尝试的另一种方法是使用GetFileByServerRelativeUrl 获取特定文件:

File file = clientContext.Web.GetFileByServerRelativeUrl(serverRelativeUrl);
clientContext.Load(file);
clientContext.ExecuteQuery();

这给了我以下错误:

Microsoft.SharePoint.Client.ServerUnauthorizedAccessException: '访问被拒绝。您无权执行此操作或访问此资源。'

是的,我已经检查过了 - 我确实拥有此库的完全权限,并且它处于默认设置,因此项目级权限不会与库的权限有所不同。

有没有人知道我做错了什么或如何正确做?实际目标是通过文件名访问库中的特定文件,文件列表也可以。

【问题讨论】:

  • 您能否发布您的AppManifest.xml 中显示AppPermissionRequests 部分的部分?从你所说的应用程序权限是错误的,即使你这样做,它也无权访问列表项。
  • @Equalsk 我的AppManifest.xml 不包含任何AppPermissionRequestssection。我只有PropertiesTitleStartPage,以及AppPrincipalRemoteWebApplication
  • 应用程序是要在当前用户的上下文中运行,还是只需要应用程序权限运行?
  • @Equalsk 既然你提到了它......使用仅限应用程序的权限运行可能会更好。我现在将其更改为 CreateAppOnlyClientContextForSPHost() 并设置 <AppPermissionRequests AllowAppOnlyPolicy="true" /> 但代码的行为完全相同:(
  • 您要求的范围是什么?应该有一条看起来像 <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Write"/> 的行(您的行可能会因需要而异)

标签: c# asp.net-mvc sharepoint sharepoint-apps


【解决方案1】:

您是否尝试以管理员身份启动 Visual Studio? 如果这解决了您的问题,您可能需要一个清单文件并在所需的管理员内部进行更改。 当您尝试访问不属于 Windows 用户的文件时,通常会发生这种情况,这意味着根文件夹 (C:)。

【讨论】:

  • 不幸的是,我的 PC 上没有管理员权限,因此无法以管理员身份运行 VS。但是权限部分应该被上下文覆盖。我的意思是整个 SP 不是 Windows 用户的一部分,但我可以读取文档库中的项目数量。
【解决方案2】:

我以前做过这类事情,但我没有使用 C#。如果您想尝试另一种方式,有一种称为 PnP PowerShell 的 PowerShell 方法,可以轻松访问 SharePoint 应用程序并返回内容(微软官方认可)。你可以试试:

Get-PnPListItem -List <ListPipeBind>
            [-Fields <String[]>]
            [-PageSize <Int>]
            [-ScriptBlock <ScriptBlock>]
            [-Web <WebPipeBind>]
            [-Connection <SPOnlineConnection>]

返回列表中的所有项目(请记住,文档库只是一个特殊列表,如任务列表或其他),有些版本的 cmdlet 仅返回 1 个项目。

例如:

PS:> Get-PnPListItem -List Tasks -PageSize 1000

返回任务列表的前 1000 个元素。

这里是主要的github:https://github.com/SharePoint/PnP-PowerShell/tree/master/Documentation

这里是 cmdlet 文档:https://github.com/SharePoint/PnP-PowerShell/blob/master/Documentation/Get-PnPListItem.md

【讨论】:

  • 感谢您展示这种替代方式,但我更愿意坚持使用 C#。
  • 如你所愿,但我从未使用 C# 访问 SharePoint 站点,因为 PnP PowerShell 更容易更好。
  • 所以似乎没有其他任何工作,我正在尝试使用 powerShell.AddCommand("Get-PnPFile -Url " + serverRelativeUrl + " -AsFile"); 的方法。我已经设法在 C# 中包含 PS 代码,并且之后可能有代码来捕获结果。我的问题是 - 我如何包含整个 PnP 库?该命令未被识别。我可能需要一些Import-Module,但我从哪里导入?文档只提供了 .msi,但这不是只在我的 PC 上安装模块而不是 Visual Studio 解决方案吗?
  • 要使用 PnP PowerShell,您需要下载并安装 SharePoint Online 命令行管理程序。然后通过 PnP github 主页给出的命令安装 PnP 包。但我认为它们只能在您需要下载的管理外壳中使用。我知道为 SharePoint 网站制作第三方程序很痛苦,如果您无法做到,请在 LinkedIn 上与我联系“Erwan Tassin”。
【解决方案3】:

我可以尝试给出的另一个答案是,您是否直接从服务器位置运行您的代码?我有时需要这样做才能使我的一些程序正常工作。

【讨论】:

  • 我不知道如何回答这个问题。好吧,该应用程序当前在我的本地主机上运行,​​但它连接到一个显然在线的 Sharepoint 站点。
  • 您是否拥有 SharePoint 网站的完整管理员权限?
  • 我在 Owners 组中,拥有“完全控制”权限级别。
  • 那我就想不通了。尝试使用 powershell 答案,MS SP 充满了错误,甚至 MS 也不理解并且支持非常薄弱。而使用 PnP PowerShell,只需 5 行代码,您就可以将结果通过管道传输到 .csv 文件中,并且很快就完成了。
  • 问题是,我需要访问我的 C# 代码 的特定文件。因此,我实际上需要文件的流。我曾经使用它将 docx 转换为 pdf(使用 word 自动化服务),并有几次以 WordprocessingDocument 的形式打开 docx 并阅读或修改内容。
【解决方案4】:

要访问列表项的文件,您需要访问列表项本身,并在上下文中加载其File 属性:

var docs = clientContext.Web.Lists.GetByTitle(Library);
var listItem = docs.GetItemById(listItemId);
clientContext.Load(docs);
clientContext.Load(listItem, i => i.File);
clientContext.ExecuteQuery();

var fileRef = listItem.File.ServerRelativeUrl;

您确定有ID = 1 的文件吗?使用您的代码:

var templateListItems = templateList.GetItems(CamlQuery.CreateAllItemsQuery());

clientContext.Load(templateListItems);

clientContext.ExecuteQuery();

获取所有项目,并检查它们的 ID。

编辑

根据您的评论 - 您是否尝试过使用不同的查询(编写您自己的)来根据规则检索一些项目。因为templateList.ItemCount 属性为您提供了一些价值,但这并不意味着您已正确加载项目。这意味着您已经加载了列表。

查询有问题。从我在所有示例中看到的情况来看,他们正在创建这样的查询:

var query = CamlQuery.CreateAllItemsQuery();
var templateListItems = templateList.GetItems(query);

我知道这似乎不会破坏交易,但你知道 - SharePoint...值得一试。

【讨论】:

  • 我的问题不是访问项目的File 属性,而是访问列表中的项目。正如问题中已经说明的那样,我的templateListItems 代码给了我templateListItems.Count = 0,因此我不能用它来“获取所有项目并检查它们的ID”“获取所有项目” 是实际问题。是的,我很确定身份证。我让 Sharepoint 向我展示了库中的 id,由于尚未触及库,因此 8 个文件的 id 实际上是从 1 到 8。
  • 我也试过这种方式,查询是单独定义的,但这和之前的一样 - templateListItems.Count = 0
【解决方案5】:

我终于让它工作了!事实证明,SharePoint 上的权限有问题。

在 SharePoint 上,在 “正在测试的应用程序” 选项卡中,您可以单击应用程序旁边的 “...”,转到 “管理权限”,您将被转到一个页面,询问您“您信任 XXX 吗?”。我非常专注于问题以及 “信任它”“取消” 按钮,以至于我没有看到左侧的下拉菜单说 “让它完全控制列表:" 预选了 "App Packages"。当我将其更改为我试图访问的列表时,我的代码中的一种方法突然起作用了:

List templateList = web.Lists.GetByTitle(libraryName);
clientContext.Load(templateList);
clientContext.ExecuteQuery();

ListItemCollection templateListItems = templateList.GetItems(CamlQuery.CreateAllItemsQuery());
clientContext.Load(templateListItems);
clientContext.ExecuteQuery();

现在templateListItems 实际上包含了我库中的对象!

当然可以“优化”代码并删除第一个ExecuteQuery(),或者将CamlQuery.CreateAllItemsQuery()定义为一个单独的变量并将其传递给GetItems(),或者使用vars而不是显式类型-全部在这些工作中,这取决于您的喜好。

感谢所有帮助,我希望我已经从这里得到它:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多