foreach(SPSite site in webapp.Sites)
{
//TODO: your code here
}
Everything works fine if Administrator did not lock any site in site collection. The administrator can go to Central Administration -> Application Management -> Site quote and lock, then perform the locking for one of site in site collection. Of course the code you won't work correctly and throw an exception:
Microsoft.SharePoint.SPException: Access to this Web site has been blocked.Please contact the administrator to resolve this problem. ---> System.Runtime.InteropServices.COMException (0x81020071): <nativehr>0x81020071</nativehr><nativestack></nativestack>Access to this Web site has been blocked.Please contact the administrator to resolve this problem. at Microsoft.SharePoint.Library.SPRequestInternalClass.OpenWebInternal(String bstrUrl, Guid& pguidID, String& pbstrRequestAccessEmail, UInt32& pwebVersion, String& pbstrServerRelativeUrl, UInt32& pnLanguage, UInt32& pnLocale, String& pbstrDefaultTheme, String& pbstrDefaultThemeCSSUrl, String&
To avoid the exception happens and the code will still continue if the site cannot access to, we should use the try/catch block to bypass the error:
foreach(SPSite site in webapp.Sites)
{
try
{
//TODO: your code here
}
catch(Exception ex)
{
//Log the error here to know which site cannot be accessed
}
finally
{
//if you have an opening site to get the property from SPWeb, please close before dispose SPSite object
site.Close();
site.Dispose();
}
}
The code above worked fine and everything seems to be right, but it's not the best practice here for a large site collection. Assume we need to loop for more than 1 thousand site in site collection, it's for sure that the code above is not good because everytime exception happens, the object exception must be initilized and go through final block to close and dispose object model.
In this topic, I would like to check if the site cannot be accessed, we will bypass and continue on another site, the code will change:
foreach(SPSite site in webapp.Sites)
{
FieldInfo fi = typeof(SPSite).GetField("bitField", BindingFlags.Instance | BindingFlags.NonPublic);
if (fi == null)
{
continue;
}
SPSite.BitField bitField = (SPSite.BitField)fi.GetValue(site);
//check if locked site
bool IsReadLock = (bitField & SPSite.BitField.readLock) > (SPSite.BitField)0u;
bool IsWriteLock = (bitField & SPSite.BitField.writeLock) > (SPSite.BitField)0u;
if (IsReadLock || IsWriteLock)
{
continue;
}
//TODO: Your code here
}
Now, there is no try/catch block to receive the exception but there is no exception in this case, because we don't go and work on locked site.
Any another suggestion are welcome.
Hope this help.
No comments:
Post a Comment