コード スニペット: クライアントの外部リストからアイテム データを取得する
最終更新日: 2010年4月19日
適用対象: SharePoint Server 2010
この記事の内容
説明
前提条件
この例を使用するには
説明
次のコード スニペットは、SharePoint クライアント オブジェクト モデルを使用して、外部リストのリスト アイテム データをクライアント コンピューターから取得する方法を示します。
重要 |
---|
外部リストの ListItem データの "既定の" ClientContext.Load を使用すると、"指定されたキーはディレクトリ内に存在しませんでした。" というエラーが表示されます。代わりに、使用するフィールドを CamlQuery メソッドと、さらに ClientContext.Load メソッドで明示的に指定する必要があります。 |
前提条件
サーバー上の Microsoft SharePoint Server 2010 あるいは Microsoft SharePoint Foundation 2010。
サーバー上の少なくとも 1 つの外部リスト。
クライアント コンピューター上の Microsoft Office Professional Plus 2010 と Microsoft .NET Framework 3.5。
Microsoft Visual Studio。
この例を使用するには
クライアント コンピューターで Visual Studio を開始し、C# コンソール アプリケーション プロジェクトを作成します。プロジェクトを作成するときに、[.NET Framework 3.5] を選択します。
[表示] メニューから、[プロパティ ページ] をクリックしてプロジェクト プロパティを表示します。
[ビルド] タブから、[プラットフォーム ターゲット] で、[Any CPU] を選択します。
プロジェクト プロパティ ウィンドウを閉じます。
[ソリューション エクスプローラー] の [参照設定] で、[System] と [System.Core] を除いて、すべてのプロジェクト参照を削除します。
プロジェクトに以下の参照を追加します。
Microsoft.SharePoint.Client
Microsoft.SharePoint.Client.Runtime
System.Data.Linq
System.XML
この手順の最後に示すコードで、Program.cs で自動生成されたコードを置換します。
<TargetSiteUrl> と <TargetListName> の値を有効な値で置換します。
プロジェクトを保存します。
プロジェクトをコンパイルして、実行します。
using System;
using Microsoft.SharePoint.Client;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Text;
using System.Globalization;
namespace Microsoft.SDK.Sharepoint.Samples
{
/// <summary>
/// This example shows how to retrieve list item data
/// from an external list.
///
/// You'll need to explicitly specify the field data in both
/// the CAML query and also ClientContext.Load.
/// </summary>
class Program
{
// Note: Replace these with your actual Site URL and List name.
private static string TargetSiteUrl = "<TargetSiteUrl>";
private static string TargetListName = "<TargetListName>";
/// <summary>
/// Example to show using CSOM to retrieve external List data.
/// </summary>
static void Main(string[] args)
{
ClientContext clientContext = new ClientContext(TargetSiteUrl);
List externalList = clientContext.Web.Lists.GetByTitle(
TargetListName);
// To properly construct the CamlQuery and
// ClientContext.LoadQuery,
// we need some View data of the Virtual List.
// In particular, the View will give us the CamlQuery
// Method and Fields.
clientContext.Load(
externalList.Views,
viewCollection => viewCollection.Include(
view => view.ViewFields,
view => view.HtmlSchemaXml));
// This tells us how many list items we can retrieve.
clientContext.Load(clientContext.Site,
s => s.MaxItemsPerThrottledOperation);
clientContext.ExecuteQuery();
// Let's just pick the first View.
View targetView = externalList.Views[0];
string method = ReadMethodFromViewXml(
targetView.HtmlSchemaXml);
ViewFieldCollection viewFields = targetView.ViewFields;
CamlQuery vlQuery = CreateCamlQuery(
clientContext.Site.MaxItemsPerThrottledOperation,
method,
viewFields);
Expression<Func<ListItem, object>>[] listItemExpressions =
CreateListItemLoadExpressions(viewFields);
ListItemCollection listItemCollection =
externalList.GetItems(vlQuery);
// Note: Due to limitation, you currently cannot use
// ClientContext.Load.
// (you'll get InvalidQueryExpressionException)
IEnumerable<ListItem> resultData = clientContext.LoadQuery(
listItemCollection.Include(listItemExpressions));
clientContext.ExecuteQuery();
foreach (ListItem li in resultData)
{
// Now you can use the ListItem data!
// Note: In the CamlQuery, we specified RowLimit of
// MaxItemsPerThrottledOperation.
// You may want to check whether there are other rows
// not yet retrieved.
}
}
/// <summary>
/// Parses the viewXml and returns the Method value.
/// </summary>
private static string ReadMethodFromViewXml(string viewXml)
{
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.ConformanceLevel = ConformanceLevel.Fragment;
XmlReader xmlReader = XmlReader.Create(
new StringReader(viewXml), readerSettings);
while (xmlReader.Read())
{
switch (xmlReader.NodeType)
{
case XmlNodeType.Element:
if (xmlReader.Name == "Method")
{
while (xmlReader.MoveToNextAttribute())
{
if (xmlReader.Name == "Name")
{
return xmlReader.Value;
}
}
}
break;
}
}
throw new Exception("Unable to find Method in View XML");
}
/// <summary>
/// Creates a CamlQuery based on the inputs.
/// </summary>
private static CamlQuery CreateCamlQuery(
uint rowLimit, string method, ViewFieldCollection viewFields)
{
CamlQuery query = new CamlQuery();
XmlWriterSettings xmlSettings = new XmlWriterSettings();
xmlSettings.OmitXmlDeclaration = true;
StringBuilder stringBuilder = new StringBuilder();
XmlWriter writer = XmlWriter.Create(
stringBuilder, xmlSettings);
writer.WriteStartElement("View");
// Specifies we want all items, regardless of folder level.
writer.WriteAttributeString("Scope", "RecursiveAll");
writer.WriteStartElement("Method");
writer.WriteAttributeString("Name", method);
writer.WriteEndElement(); // Method
if (viewFields.Count > 0)
{
writer.WriteStartElement("ViewFields");
foreach (string viewField in viewFields)
{
if (!string.IsNullOrEmpty(viewField))
{
writer.WriteStartElement("FieldRef");
writer.WriteAttributeString("Name", viewField);
writer.WriteEndElement(); // FieldRef
}
}
writer.WriteEndElement(); // ViewFields
}
writer.WriteElementString(
"RowLimit", rowLimit.ToString(CultureInfo.InvariantCulture));
writer.WriteEndElement(); // View
writer.Close();
query.ViewXml = stringBuilder.ToString();
return query;
}
/// <summary>
/// Returns an array of Expression used in
/// ClientContext.LoadQuery to retrieve
/// the specified field data from a ListItem.
/// </summary>
private static Expression<Func<ListItem, object>>[]
CreateListItemLoadExpressions(
ViewFieldCollection viewFields)
{
List<Expression<Func<ListItem, object>>> expressions =
new List<Expression<Func<ListItem, object>>>();
foreach (string viewFieldEntry in viewFields)
{
// Note: While this may look unimportant,
// and something we can skip, in actuality,
// we need this step. The expression should
// be built with local variable.
string fieldInternalName = viewFieldEntry;
Expression<Func<ListItem, object>>
retrieveFieldDataExpression =
listItem => listItem[fieldInternalName];
expressions.Add(retrieveFieldDataExpression);
}
return expressions.ToArray();
}
}
}