1
votes

During some Read/Write/Update operations SharePoint Client Object model returns '(503) Service Unavailable' exception, reattempt solve this problem. Here, re-attempt Operation creates a new collection of return values and we are not able to assign it back to the original return value object.

Note: Return value of LoadQuery() method is present in 'ClientQueryableResult.m_data' private variable.

We come up with below reflection code. But the problem is we are not sure whether it is safe to use Reflection with SharePoint Client object module to read one of it's private variable value?

e.g. Loading SharePoint Groups we have

var groups = _ClientContext.LoadQuery(_ClientContext.Web.SiteGroups);

_ClientContext.ExecuteQuery();

Below code caches LoadQuery() parameters and use it in exception case for reattempt

object OrgResult, NewResult, Params;
    Params = clientObjects
    OrgResult = _ClientContext.LoadQuery(clientObjects);
    try   {_ClientContext.ExecuteQuery();}
    catch (WebException webEx){
    NewResult = _ClientContext.LoadQuery(Params);
    _ClientContext.ExecuteQuery();
    object data = NewResult.GetPrivateFieldValue("m_data");
    if (data != null)
        OrgResult.SetPrivateFieldValue("m_data", data);
    }

    // Reflection method to read private value
    public static object GetPrivateFieldValue(this object src, string fieldName)
    {
    object value = null;
    FieldInfo fieldInfo = src.GetType().GetField(fieldName, BindingFlags.NonPublic
                                                |BindingFlags.Instance);
    if (fieldInfo != null)
    value = fieldInfo.GetValue(src);
    return value;
    }
1

1 Answers

0
votes

Using a reflection based code is always unsafe as it might break in future SharePoint upgrades. You have 2 choices:

  1. Use it at your own risk. Any upgrade or patch might break it.

  2. Find out the root cause of the issue. You are saying that re-attempt to evaluate the expression results in success. You should be able to refactor your design in such a way that it always attempts to read twice before giving up an error to the user.

I have used client object model a lot and have not came across this issue. Hence I would prefer you go via route 2. But if you are really stuck across some rare issue which cannot be solved now, go with route 1.