SharePointのクライアントオブジェクトモデルを使用していて、初期化されていない、またはによって取得されていないプロパティにアクセスする場合
Context.Load(property);
Context.ExecuteQuery();
たとえば、次のようになります。
Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException
または
コレクションは初期化されていません。リクエストされていないか、リクエストが実行されていません。
例外。
これらのプロパティがすでに初期化/取得されているかどうかを確認する前に、適切な方法はありますか?トライ/キャッチアプローチなし。私はそれが好きではありません。
例外がスローされる前に確認して処理したいと思います。
私はすでにチェックしました
方法ですが、実際には役に立ちません。 IsPropertyAvaiable
はスカラープロパティのみをチェックし、たとえばWeb.Lists
では結果を返しません。Web.Lists
は初期化されていませんが、IsObjectPropertyInstantiated
はWeb.Lists
に対してtrueを返します。
あなたの質問にはすでにある程度正しい答えが含まれていると思います。
クライアントオブジェクトプロパティがロードされているかどうかを判断するには、次のメソッドを使用できます。
テストケース1:スカラープロパティのみをロード
ctx.Load(ctx.Web, w => w.Title);
ctx.ExecuteQuery();
//Results:
ctx.Web.IsObjectPropertyInstantiated("Lists") False
ctx.Web.IsPropertyAvailable("Title") True
テストケース2:複合プロパティのみをロード
ctx.Load(ctx.Web, w => w.Lists);
ctx.ExecuteQuery();
//Results:
ctx.Web.IsObjectPropertyInstantiated("Lists") True
ctx.Web.IsPropertyAvailable("Title") False
テストケース3:スカラープロパティと複合プロパティの両方をロードする
ctx.Load(ctx.Web, w=>w.Lists,w=>w.Title);
ctx.ExecuteQuery();
//Results
ctx.Web.IsObjectPropertyInstantiated("Lists") True
ctx.Web.IsPropertyAvailable("Title") True
ClientObject.IsPropertyAvailable および ClientObject.IsObjectPropertyInstantiated メソッドは、プロパティ名が文字列値として指定されることを想定しているため、タイプミスが発生する可能性があるため、通常は次のようにします 拡張メソッド :
public static class ClientObjectExtensions
{
/// <summary>
/// Determines whether Client Object property is loaded
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="clientObject"></param>
/// <param name="property"></param>
/// <returns></returns>
public static bool IsPropertyAvailableOrInstantiated<T>(this T clientObject, Expression<Func<T, object>> property)
where T : ClientObject
{
var expression = (MemberExpression)property.Body;
var propName = expression.Member.Name;
var isCollection = typeof(ClientObjectCollection).IsAssignableFrom(property.Body.Type);
return isCollection ? clientObject.IsObjectPropertyInstantiated(propName) : clientObject.IsPropertyAvailable(propName);
}
}
使用法
using (var ctx = new ClientContext(webUri))
{
ctx.Load(ctx.Web, w => w.Lists, w => w.Title);
ctx.ExecuteQuery();
if (ctx.Web.IsPropertyAvailableOrInstantiated(w => w.Title))
{
//...
}
if (ctx.Web.IsPropertyAvailableOrInstantiated(w => w.Lists))
{
//...
}
}
Vadim Gremyachevが提供するテストは、ctx.Loadを使用するシナリオの半分しかカバーしていません。ただし、ctx.LoadQueryを使用すると、結果が変わります。
var query = from lst in ctx.Web.Lists where lst.Title == "SomeList" select lst;
var lists = ctx.LoadQuery(query);
ctx.ExecuteQuery();
ctx.Web.IsObjectPropertyInstantiated("Lists") -> True
ctx.Web.Lists.ServerObjectIsNull -> False
ctx.Web.Lists.Count -> CollectionNotInitializedException
したがって、コレクションでLoadQueryが呼び出されると、コレクションが実際に使用可能かどうかを確認できなくなります。
この場合の唯一の方法は、例外が発生したことを検出することです。
拡張機能を使用するというアイデアは素晴らしいですが、リストでのみ正常に機能します。拡張機能は、「オブジェクト」プロパティと「スカラー」プロパティのどちらかを選択できます。この方法では、拡張機能よりも優れていると思います。
public static bool IsPropertyAvailableOrInstantiated<T>(this T clientObject, Expression<Func<T, object>> property)
where T : ClientObject
{
var expression = (MemberExpression)property.Body;
var propName = expression.Member.Name;
var isObject = typeof(ClientObject).IsAssignableFrom(property.Body.Type); // test with ClientObject instead of ClientObjectList
return isObject ? clientObject.IsObjectPropertyInstantiated(propName) : clientObject.IsPropertyAvailable(propName);
}