SharePoint Client Object应用 包含关于操作文件和文件夹的代码
记录一些平常用SharePoint Client Object访问并管理SharePoint List或Library的例子。
首先,所有使用SharePoint Client Object的.NET工程都需要引用Microsoft.SharePoint.Client.dll和Microsoft.SharePoint.Client.Runtime.dll这两个类库。这里提供一个下载:Microsoft.SharePoint.Client.zip
下面是一些例子:
1. 从指定的List或Library中找出Folder
<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
<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
<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中创建或修改文件
<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中创建或修改文件
<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文档对象
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