If you're using the Client Object Model from SharePoint and access properties which haven't been initialized or already retrieved by an
Context.Load(property);
Context.ExecuteQuery();
you get for example a:
Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException
or
The collection has not been initialized. It has not been requests or the request has not been executed.
Exception.
Is there any proper way to check before accessing these properties if they are already initialized/retrieved? Without a Try/Catch approach. I don`t like that one's.
I want to check before a Exception has been thrown and handle it.
I already checked the
IsObjectPropertyInstantiated
IsPropertyAvailable
Methods but they don't help really. IsPropertyAvaiable
only checks scalar properties and won't give a result on for example Web.Lists
and IsObjectPropertyInstantiated
returns true for Web.Lists
although Web.Lists
was not initialized.
I would say your question is already contains the correct answer to some extent.
In order to determine whether client object property is loaded or not the following methods are available:
Test case 1: load scalar property only
ctx.Load(ctx.Web, w => w.Title);
ctx.ExecuteQuery();
//Results:
ctx.Web.IsObjectPropertyInstantiated("Lists") False
ctx.Web.IsPropertyAvailable("Title") True
Test case 2: load composite property only
ctx.Load(ctx.Web, w => w.Lists);
ctx.ExecuteQuery();
//Results:
ctx.Web.IsObjectPropertyInstantiated("Lists") True
ctx.Web.IsPropertyAvailable("Title") False
Test case 3: load both scalar and composite properties
ctx.Load(ctx.Web, w=>w.Lists,w=>w.Title);
ctx.ExecuteQuery();
//Results
ctx.Web.IsObjectPropertyInstantiated("Lists") True
ctx.Web.IsPropertyAvailable("Title") True
Since ClientObject.IsPropertyAvailable and ClientObject.IsObjectPropertyInstantiated methods expect the property name to be specified as a string value and that could lead to typos, I usually prefer the following extension method:
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);
}
}
Usage
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))
{
//...
}
}
The tests provided by Vadim Gremyachev only cover one half of the scenarios - where you use ctx.Load. But when you use ctx.LoadQuery the result changes:
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
So once the LoadQuery has been called on a collection, you can no longer see if the collection is actually available.
Only way in this case is to detect that the exception occurs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With