SharePoint Client Object应用 包含关于操作文件和文件夹的代码

记录一些平常用SharePoint Client Object访问并管理SharePoint List或Library的例子。

  首先,所有使用SharePoint Client Object的.NET工程都需要引用Microsoft.SharePoint.Client.dllMicrosoft.SharePoint.Client.Runtime.dll这两个类库。这里提供一个下载:Microsoft.SharePoint.Client.zip

下面是一些例子:

1. 从指定的List或Library中找出Folder

SharePoint Client Object应用 包含关于操作文件和文件夹的代码-DESTLIVE

///
 
<summary>


///
 Get folder in the specific SharePoint List.

///
 
</summary>


///
 
<param name="clientContext"></param>


///
 
<param name="listName"></param>


///
 
<param name="folderServerRelativeUrl"></param>


///
 
<returns>
 If the folder does not exist in the specific SharePoint List return null, else return the folder object.
</returns>


public 
static Folder GetFolderInList(ClientContext clientContext, String listName, String folderServerRelativeUrl)

{

    Folder existingFolder = 
null;



    Web web = clientContext.Web;

    ListCollection lists = web.Lists;

    existingFolder = web.GetFolderByServerRelativeUrl(folderServerRelativeUrl);

    clientContext.Load(existingFolder);



    
try

    {

        clientContext.ExecuteQuery();

    }

    
catch 

    {

        existingFolder = 
null;

    }



    
return existingFolder;

}

   listName为所要查询的List或Library的名称,不带路径URL。folderServerRelativeUrl为所要查询的Folder的相对路径,如“/sitename/library/folder/subfolder/”。使用的时候需要传入ClientContext对象。如果待查询的Folder存在则返回对应的Microsoft.SharePoint.Client.Folder对象,否则返回null。

 

2. 从指定的URL中确定已存在的Folder

SharePoint Client Object应用 包含关于操作文件和文件夹的代码-DESTLIVE

///
 
<summary>


///
 Find the exist folder in the given URL.

///
 
</summary>


///
 
<param name="clientContext"></param>


///
 
<param name="listName"></param>


///
 
<param name="folderServerRelativeUrl"></param>


///
 
<returns>
Returns the existed SharePoint Folder object.
</returns>


private 
static Folder FindExistFolder(ClientContext clientContext, 
string listName, 
string folderServerRelativeUrl)

{

    Web web = clientContext.Web;

    List list = web.Lists.GetByTitle(listName);



    Folder folder = GetFolderInList(clientContext, listName, folderServerRelativeUrl);



    
if (folder == 
null)

    {

        
int iLastSlashPos = folderServerRelativeUrl.LastIndexOf(
"
/
");

        
if (iLastSlashPos > 
0)

        {

            
//
 if current folder does not exist, back to the parent folder.

            
string parentFolderUrl = folderServerRelativeUrl.Substring(
0, iLastSlashPos);

            
return FindExistFolder(clientContext, listName, parentFolderUrl);

        }

    }

    
return folder;

}

  listName为所要查询的List或Library的名称,不带路径URL。folderServerRelativeUrl为所要查询的Folder的相对路径,如“/sitename/library/folder/subfolder/”。使用的时候需要传入ClientContext对象。该方法通过递归调用的方式从给定的URL中找出从哪一级开始的Folder在List或Library中是存在的。例如,给定一个Folder的相对地址“/sitename/library/folder/subfolder1/subfolder1_1/subfolder1_1_1/”,该方法将从最后一个folder开始进行递归,返回存在的那个Folder对象。如果所有的folder均不存在,则返回null。

 

3. 通过给定的URL在List或Library中创建Folder

SharePoint Client Object应用 包含关于操作文件和文件夹的代码-DESTLIVE

///
 
<summary>


///
 Check if the folder exists in the target list, if it does not, create the folders level by level.

///
 
</summary>


///
 
<param name="clientContext"></param>


///
 
<param name="listName"></param>


///
 
<param name="folderServerRelativeUrl"></param>


public 
static 
void EnsureFolderExist(ClientContext clientContext, 
string listName, 
string folderServerRelativeUrl)

{

    
//
 Remove the last character '/' from the string folderServerRelativeUrl.

    
if (folderServerRelativeUrl.Length > 
0 && folderServerRelativeUrl.Last().Equals(
'
/
'))

    {

        folderServerRelativeUrl = folderServerRelativeUrl.Substring(
0, folderServerRelativeUrl.Length - 
1);

    }



    Web web = clientContext.Web;

    List list = web.Lists.GetByTitle(listName);



    Folder folder = FindExistFolder(clientContext, listName, folderServerRelativeUrl);



    
if (folder != 
null)

    {

        
//
 Get the new folders path string part.

        
string s = folderServerRelativeUrl.Replace(folder.ServerRelativeUrl, 
string.Empty);

        
if (s.Length > 
0 && s.First().Equals(
'
/
'))

        {

            s = s.Substring(
1, s.Length - 
1);

        }



        
string[] arr = s.Split(
'
/
');

        
if (arr.Length > 
0)

        {

            
string tmp = 
string.Empty;

            
//
 Create new folders level by level.

            
for (
int i = 
0; i < arr.Length; i++)

            {

                
if (arr[i].Trim().Length > 
0)

                {

                    tmp += 
"
/
" + arr[i];

                    folder.Folders.Add(folder.ServerRelativeUrl + tmp);

                    clientContext.Load(folder);

                    clientContext.ExecuteQuery();

                }

            }

        }

    }

}

  顾名思义,该方法借助于FindExistFolder方法首先从给定的folder相对路径中找出已存在的folder,然后逐级创建folder。

 

4. 使用Microsoft.SharePoint.Client.FileCollection.Add方法向目标Library中创建或修改文件

SharePoint Client Object应用 包含关于操作文件和文件夹的代码-DESTLIVE

///
 
<summary>


///
 Upload a document to the specific SharePoint List.

///
 
</summary>


///
 
<param name="clientContext"></param>


///
 
<param name="listName"></param>


///
 
<param name="documentUrl">
The target document path, e.g. /site/library/folder/word1.docx.
</param>


///
 
<param name="documentStream"></param>


///
 
<param name="contentType">
ContentType string
</param>


public 
static 
void UploadFileToList(ClientContext clientContext, 
string listName, 
string documentUrl, 
byte[] documentStream, 
string contentType)

{

    Web web = clientContext.Web;

    List list = web.Lists.GetByTitle(listName);

    
bool bTarFileExist = 
true;



    
//
 Try to load the target document.

    Microsoft.SharePoint.Client.File targetFile = web.GetFileByServerRelativeUrl(documentUrl);

    targetFile.RefreshLoad();

    clientContext.Load(targetFile);



    
try

    {

        clientContext.ExecuteQuery();

    }

    
catch 

    {

        bTarFileExist = 
false;

    }



    
//
 If the target document does exist.

    
if (bTarFileExist)

    {

        
//
 If the target document is checked out by another user, execute UndoCheckOut.

        
if (targetFile.CheckOutType != CheckOutType.None)

        {

            targetFile.UndoCheckOut();

        }



        
//
 Check out the target document before uploading.

        targetFile.CheckOut();

    }



    
//
 Construct the target document object.

    FileCreationInformation newItemInfo = 
new FileCreationInformation();

    newItemInfo.Content = documentStream;

    newItemInfo.Overwrite = 
true;

    newItemInfo.Url = documentUrl;

    Microsoft.SharePoint.Client.File uploadFile = list.RootFolder.Files.Add(newItemInfo);



    
//
 Get target file ContentType.

    ContentType newFileContentType = 
null;

    
if (!defaultContentTypes.Contains(contentType))

    {

        ContentTypeCollection listContentTypes = list.ContentTypes;

        clientContext.Load(listContentTypes, types => types.Include(type => type.Id, type => type.Name, type => type.Parent));

        
var result = clientContext.LoadQuery(listContentTypes.Where(c => c.Name == contentType));

        clientContext.ExecuteQuery();

        newFileContentType = result.FirstOrDefault();

    }



    
//
 Set target file ContentType with the correct value.

    clientContext.Load(uploadFile.ListItemAllFields);

    
if (newFileContentType != 
null)

    {

        uploadFile.ListItemAllFields[
"
ContentTypeId
"] = newFileContentType.Id.ToString();

    }

    uploadFile.ListItemAllFields.Update();

    

    
//
 Check in the docuemnt with a draft version.

    uploadFile.CheckIn(
string.Empty, CheckinType.MinorCheckIn);

    
//
 Excute the document upload.

    clientContext.ExecuteQuery();

}

  该方法首先根据传入的documentUrl判断文件是否已经存在,如果存在则需要先将文件check out或undo check out,然后通过Microsoft.SharePoint.Client.FileCollection.Add的方式上传文件。如果目标library中有ContextType的限制,则还需要指定文件的ContentType,defaultContentTypes是一个存放指定ContentType的静态String数组,如果传入的contentType字符串不在defaultContentTypes数组中,则需要给文件指定新的ContentType。

 

5. 使用Microsoft.SharePoint.Client.File.SaveBinaryDirect方法向目标Library中创建或修改文件

SharePoint Client Object应用 包含关于操作文件和文件夹的代码-DESTLIVE

///
 
<summary>


///
 Upload a document to the specific SharePoint List.

///
 
</summary>


///
 
<param name="clientContext"></param>


///
 
<param name="listName"></param>


///
 
<param name="documentUrl">
The target document path, e.g. /site/library/folder/word1.docx.
</param>


///
 
<param name="fs"></param>


///
 
<param name="contentType"></param>


public 
static 
void UploadFileToListByFileStream(ClientContext clientContext, 
string listName, 
string documentUrl, FileStream fs, 
string contentType)

{

    Web web = clientContext.Web;

    List list = web.Lists.GetByTitle(listName);

    
bool bTarFileExist = 
true;



    
//
 Try to load the target document.

    Microsoft.SharePoint.Client.File targetFile = web.GetFileByServerRelativeUrl(documentUrl);

    targetFile.RefreshLoad();

    clientContext.Load(targetFile);



    
try

    {

        clientContext.ExecuteQuery();

    }

    
catch

    {

        bTarFileExist = 
false;

    }



    
//
 If the target document does exist.

    
if (bTarFileExist)

    {

        
//
 If the target document is checked out by another user, execute UndoCheckOut.

        
if (targetFile.CheckOutType != CheckOutType.None)

        {

            targetFile.UndoCheckOut();

        }



        
//
 Check out the target document before uploading.

        targetFile.CheckOut();

        clientContext.ExecuteQuery();

    }



    
//
 Upload file.

    Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, documentUrl, fs, 
true);

    

    
//
 Get the new file.

    Microsoft.SharePoint.Client.File newFile = web.GetFileByServerRelativeUrl(documentUrl);

    newFile.RefreshLoad();

    clientContext.Load(newFile);

    clientContext.ExecuteQuery();



    
//
 Get target file ContentType.

    ContentType newFileContentType = 
null;

    
if (!defaultContentTypes.Contains(contentType))

    {

        ContentTypeCollection listContentTypes = list.ContentTypes;

        clientContext.Load(listContentTypes, types => types.Include(type => type.Id, type => type.Name, type => type.Parent));

        
var result = clientContext.LoadQuery(listContentTypes.Where(c => c.Name == contentType));

        clientContext.ExecuteQuery();

        newFileContentType = result.FirstOrDefault();



        
//
 Set new file ContentType with the correct value.

        clientContext.Load(newFile.ListItemAllFields);

        newFile.ListItemAllFields[
"
ContentTypeId
"] = newFileContentType.Id.ToString();

        newFile.ListItemAllFields.Update();

    }



    
//
 Check in the docuemnt with a draft version.

    newFile.CheckIn(
string.Empty, CheckinType.MinorCheckIn);

    
//
 Excute the document upload.

    clientContext.ExecuteQuery();

}

  与UploadFileToList方法类似,该方法通过Microsoft.SharePoint.Client.File.SaveBinaryDirect方法向目标Library中上传文件,接收FileStream而不是文件的字节数组。

 

6. 读取List或Library中的数据并返回指定格式的XML文档对象

SharePoint Client Object应用 包含关于操作文件和文件夹的代码-DESTLIVE

public 
static XDocument GetXmlFromLibrary(
string siteUrl, 
string listName)

{

    
string host = (
new Uri(siteUrl)).Host;

    XElement root = 
new XElement(
"
Items
");



    
using (ClientContext clientContext = 
new ClientContext(siteUrl))

    {

        Web web = clientContext.Web;

        List list = web.Lists.GetByTitle(listName);



        CamlQuery camlQuery = 
new CamlQuery();

        camlQuery.ViewXml = 
@"
<View>
                                <ViewFields>
                                  <FieldRef Name='Title'/>
                                  <FieldRef Name='InsideTrackCategories'/>
                                </ViewFields>
                                <RowLimit>0</RowLimit>
                              </View>

";



        ListItemCollection listItems = list.GetItems(camlQuery);

        clientContext.Load(list);

        
//
clientContext.Load(listItems);

        clientContext.Load(listItems, s => s.Include(c => c.Id, c => c.DisplayName, c => c.FieldValuesAsText, c => c.FieldValuesForEdit));

        clientContext.ExecuteQuery();                



        
foreach (ListItem item 
in listItems)

        {

            XElement eleTitle = 
new XElement(
"
Title
", item.FieldValuesAsText[
"
Title
"].ToString());

            XElement eleUrl = 
new XElement(
"
Url
"
string.Concat(
"
http://
", host, item.FieldValuesAsText[
"
FileRef
"].ToString()));

            XElement eleInsideCategories = 
new XElement(
"
InsideCategories
");

            
string s = item.FieldValuesAsText[
"
InsideTrackCategories
"];

            
if (!
string.IsNullOrEmpty(s))

            {

                
string[] arr = s.Split(
'
;
');

                
foreach (
string tmp 
in arr)

                {

                    XElement eleCategory = 
new XElement(
"
Category
", tmp);

                    eleInsideCategories.Add(eleCategory);

                }

            }



            XElement eleItem = 
new XElement(
"
Item
", eleTitle, eleUrl, eleInsideCategories);

            root.Add(eleItem);

        }

    }



    XDocument doc = 
new XDocument();

    doc.Add(root);

    
return doc;

}

  该方法比较简单,通过指定的siteUrl和listName从List或Library中读取指定字段的数据,然后按照一定的格式返回XML文档对象。下面是所返回的XML文档对象的结构:

<?
xml version="1.0" encoding="utf-8"
?>


<
Items
>

  
<
Item
>

    
<
Title
></
Title
>

    
<
Url
></
Url
>

    
<
InsideCategories
>

      
<
Category
></
Category
>

      
<
Category
></
Category
>

      
<
Category
></
Category
>

    
</
InsideCategories
>

  
</
Item
>

  
<
Item
>

    
<
Title
></
Title
>

    
<
Url
></
Url
>

    
<
InsideCategories
>

      
<
Category
></
Category
>

    
</
InsideCategories
>

  
</
Item
>


</
Items
>

  字段InsideTrackCategories是Lookup类型,并且允许有多个值,当有多个值存在时,SharePoint中用分号进行分隔。

 

  这里记录一些有关SharePoint客户端对象模型应用方面的文章,方便以后查阅:

http://msdn.microsoft.com/zh-cn/library/ee857094.aspx

http://msdn.microsoft.com/en-us/library/ee956524.aspx

http://blog.csdn.net/lgm97/article/details/6455361

http://ranaictiu-technicalblog.blogspot.com/2010/03/sharepoint-2010-manage.html

http://www.cnblogs.com/Sunmoonfire/archive/2011/01/18/1937884.html