CSOM - FileRef 与 ServerUrl 与 sp.listitem.ServerRelativeUrl

CSOM - FileRef vs ServerUrl vs sp.listitem.ServerRelativeUrl

我最近一直在研究 SharePoint CSOM,并且一直在处理文档库中的文件处理(上传/下载/元数据更新)。我遇到过几种获取文件的服务器相对 url 的方法,即 listitem["FileRef"] 或 listitem.ServerRelativeUrl。这个 link a link 给出了共享点字段的内部名称列表。请注意,它将 "Server Relative URL" 列为 "ServerUrl"。但是,当我尝试访问类似 listitem["ServerUrl"] 的内容时,抛出异常:

属性 或字段尚未初始化。尚未请求或请求尚未执行。可能需要明确请求。

这是我的代码示例

    using (ClientContext clientContext = new ClientContext(siteUrl))
{
clientContext.Credentials = new NetworkCredential("abc", "abc", "cde");
List oList = clientContext.Web.Lists.GetByTitle("abcd");
clientContext.Load(oList);
clientContext.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();

ListItemCollectionPosition itemPosition = null;

conn.Open();
while (true)
{
    camlQuery = new CamlQuery();
    camlQuery.ListItemCollectionPosition = itemPosition;

        camlQuery.ViewXml =
            //@"<View Scope='RecursiveAll'>
            string.Format(@"<View Scope='RecursiveAll'>
                            <Query>
                                <Where>
                                    <And>
                                        <Eq>
                                            <FieldRef Name='FSObjType' />
                                            <Value Type='Integer'>0</Value>
                                        </Eq>
                                        <In>
                                            <FieldRef Name='FileLeafRef' />
                                            <Values>
                                                {0}
                                            </Values>
                                        </In>                                
                                    </And>
                                </Where>
                            </Query>
                            <FieldRef Name='FileLeafRef' /><FieldRef Name='FileRef'><FieldRef Name='ServerUrl'>
                            <RowLimit>100</RowLimit>
                          </View>", CAMLcoll);

    ListItemCollection listItems = oList.GetItems(camlQuery);

    clientContext.Load(listItems);
    clientContext.ExecuteQuery();
    itemPosition = listItems.ListItemCollectionPosition;

    foreach (ListItem listItem in listItems)
    {
        try
        {
            clientContext.Load(listItem, eachitem => eachitem.File.ServerRelativeUrl);
            clientContext.ExecuteQuery();
            string url = listItem["FileRef"].ToString(); //This works
            url = listItem.ServerRelativeUrl.ToString(); //This works
            url = listItem["ServerUrl"].ToString(); //This throws exception!!
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }
    if (itemPosition == null)
        break;
    //Debug.Print(itemPosition.PagingInfo);
}

我有几个问题:

  1. 这 3 种访问项目服务器相对 url 的方式有什么区别?

  2. 为什么 url = listItem["ServerUrl"].ToString() 失败?

我是 CSOM 编程的新手,所以请原谅我的无知。

谢谢

阿马尔

首先 ServerRelativeUrl 仅适用于文件 class。

所以,您的代码应该是 listItem.File.ServerRelativeUrl.ToString();

关于你第一个关于差异的问题,我认为他们给出的结果都是一样的。这意味着,FileReflistItem.File.ServerRelativeUrlServerUrl 为您提供文档库中文档的相同服务器相对路径。

关于您的第二个问题,在 SharePoint CSOM 中,您需要明确加载要使用的属性。提供了一些基本属性,但对于某些其他属性,例如您的 ServerUrl,您需要显式加载它才能使用它。

第三,您的代码正在为每个列表项执行和请求数据。这根本不需要。您可以在列表项集合中加载这些属性。

已修改、简化和优化您的代码。一定要看看:

ListItemCollection listItems = oList.GetItems(camlQuery);
clientContext.Load(listItems,items => items.Include(
                        item => item["FileRef"],
                        item => item.File.ServerRelativeUrl,
                        item => item["ServerUrl"]));
clientContext.ExecuteQuery();

itemPosition = listItems.ListItemCollectionPosition;

foreach (ListItem listItem in listItems)
{
    try
    {

        string url = listItem["FileRef"].ToString(); //This works
        url = listItem.File.ServerRelativeUrl.ToString(); //This should work
        url = listItem["ServerUrl"].ToString(); //This will work now
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}