Problem: After web parts were added to pages, visitors (users with read-only access) saw the same content in all search web parts.
Solution: The solution to this problems was to set the QueryGroupName property to unique GUID’s for all web part instances.
In my current project (SharePoint 2013, publishing site) we have a few page layout with quite a lot of search results web parts, both Search Results Web Parts and Content by Query Web Parts. In our provisioning, we use the same web part definition to provision all the web parts of the same type. This was working fine to our knowledge for a long while, until we granted visitors access to the site.
From time to time we upgrade the pages by removing all web parts and adding the updated web parts from the page layout. After these upgrades, we discovered that visitors saw the same content in all web parts that used the same web part definition for provisioning. We could fix the problem by having an user with owner access visit the page – then something wired up correctly in the background that fixed the web parts for all users. Of course this was not really a fix: In our solution we have hundreds of pages, and we upgrade all pages roughly once a month (after each sprint).
The QueryGroupName property of the web part
We found that the culprit was the QueryGroupName property of the web parts, which is a “native” property of the search web parts themselves, but it is also a property in the DataProviderJSON property of the web part defintion.
We first attempted to use the value “Default” as the property value, which was suggested by a few. Unfortunately this didn’t work. We also tried to not set the property at all, but leave it out of the web part definition, in hope that SharePoint could set a value automatically. This didn’t work either.
In all the errors above, ULS reported with the following error message for visitors (full stack trace left out):
System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)), StackTrace: at Microsoft.SharePoint.WebPartPages.SPWebPartManager.SaveChangesCore(SPLayoutProperties layoutProperties, Boolean httpGet, Boolean saveCompressed, Boolean skipRightsCheck, Boolean skipSafeAgainstScriptCheck, WebPartTypeInfo& newTypeId, Byte& newAllUsersProperties, Byte& newPerUserProperties, String& newLinks)
Setting new GUID’s with a token
The way we provision page layouts and web parts allows us to tap into the web part definitions before we add them to the page. We could therefore introduce a token “|NewGuid|” as the value of the QueryGroupName property, and on provisioning we replaced this token with a new, random GUID. This made all the web parts work again for all users.
Picture below: From the updated web part definition
We used this simple line of code to update the web part definition before we added it to the page: