Wednesday, March 15, 2017

Get Child Count in Parent List SharePoint Lookup Field


I came across a requirement where I required the number of comments
 against a post in a child list (lstComments) maintained in the Parent list (lstPost).

Below is a very efficient way to achieve this


 using (SPSite site = new SPSite(webUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList lstPost = web.Lists.TryGetList("Post");
                    SPList lstComments = web.Lists.TryGetList("Comments");

                    if (lstPost != null &&  lstComments != null )
                    {
                        SPField id= lstPost .Fields.TryGetFieldByStaticName("ID");
                        if (null != id)
                        {
                            // Create a PostID lookup field on the lstComments list.  
                            string PostIdName = lstComments .Fields.AddLookup("PostID", lstPost .ID, true);
                            SPFieldLookup PostIdField =
                                (SPFieldLookup)lstComments .Fields.GetFieldByInternalName(PostIdName );
                            PostIdField .LookupField = id.InternalName;
                            PostIdField .Update();
                            AddToDefaultView(lstComments , PostIdName );

                            // Create a CommentCount Lookup field to maintain child count in the lstPost list
                            string commentCountName = lstPost .Fields.AddLookup("CommentsCount", lstComments .ID, false);
                            SPFieldLookup commentCountField =
                                (SPFieldLookup)lstPost .Fields.GetFieldByInternalName(commentCountName );
                            commentCountField .LookupField = id.InternalName;
                            commentCountField .CountRelated = true;
                            commentCountField .Update();
                            AddToDefaultView(lstPost , commentCountName );
                        }
                    }
                }

            } 

Friday, February 10, 2017

SharePoint Distributed Cache Issue

All of a sudden my farm started throwing Distributed cache errors. My ULS filled with below log when I refreshed a page 
Unexpected Exception in SPDistributedCachePointerWrapper::InitializeDataCacheFactory for usage 'DistributedLogonTokenCache' - Exception 'Microsoft.ApplicationServer.Caching.DataCacheException: ErrorCode<ERRCA0009>:SubStatus<ES0001>:Cache referred to does not exist. Contact administrator or use the Cache administration tool to create a Cache.   
 at Microsoft.ApplicationServer.Caching.DataCache.ThrowException(ResponseBody respBody, RequestBody reqBody)   
 at Microsoft.ApplicationServer.Caching.DataCacheFactory.GetCacheProperties(RequestBody request, IClientChannel channel)   
 at Microsoft.ApplicationServer.Caching.DataCacheFactory.GetCache(String cacheName)   
 at Microsoft.SharePoint.DistributedCaching.SPDistributedCachePointerWrapper.InitializeDataCacheFactory()'.

I tried steps below and walla!

1) Go to Manage Services on Server in Central Administration and stop Distributed Cache on all Application Servers and WFEs

2) Open SharePoint Management Shell and run following commands

       a) Use-CacheCluster
       b) Get-CacheCluster | Select CacheName
Above commands should return list of 10 cache types 

CacheName            
---------          
DistributedAccessCache_<ur farm ID>
DistributedActivityFeedCache_<ur farm ID>
DistributedActivityFeedLMTCache_<ur farm ID>
DistributedBouncerCache_<ur farm ID>
DistributedDefaultCache_<ur farm ID>
DistributedLogonTokenCache_<ur farm ID>
DistributedSearchCache__<ur farm ID>
DistributedSecurityTrimmingCache_<ur farm ID>
DistributedServerToAppServerAccessTokenCache_<ur farm ID>
DistributedViewStateCache_<ur farm ID>

Incase you get nothing - you need to setup DistribtedCache again so move on to step 7

In case above list is returned move on to step 3

3) Run following command 
                   Remove-SPDistributedCacheServiceInstance

4) to check of the cache instance is removed successfully 
                   Get-Cache | Select CacheName
this should return below error

Get-Cache : ErrorCode<ERRCMS0006>:SubStatus<ES0001>:Error while loading the
provider "SPDistributedCacheClusterProvider". Check HKEY_LOCAL_MACHINE ->
SOFTWARE\Microsoft\AppFabric\V1.0\Providers\AppFabricCaching ->
SPDistributedCacheClusterProvider....

5) Now add new instance of DistributedCacheService by running following command
                                  a) Add-SPDistributedCacheServiceInstance
                                 b)  Restart-CacheCluster
this should return below

HostName : CachePort                      Service Name             Service Status            Version
                                                                                       Info
--------------------                    ------------                    --------------         ----------
<host server name>:<port>      AppFabricCachingService            UP                           3
                                                                                      [3,3][1,3]

6) check if cache is available now:
                    Get-Cache | Select CacheName
should give output as below

CacheName            
---------          
DistributedAccessCache_<ur farm ID>
DistributedActivityFeedCache_<ur farm ID>
DistributedActivityFeedLMTCache_<ur farm ID>
DistributedBouncerCache_<ur farm ID>
DistributedDefaultCache_<ur farm ID>
DistributedLogonTokenCache_<ur farm ID>
DistributedSearchCache__<ur farm ID>
DistributedSecurityTrimmingCache_<ur farm ID>
DistributedServerToAppServerAccessTokenCache_<ur farm ID>
DistributedViewStateCache_<ur farm ID>


 7) No output on running step 2) indicates that you need to setup Distributed Cache altogether

to do so first determine your farm ID 
         Get-SPFarm | Select Id 
get the output and run the following command 
       New-Cache -CacheName DistributedLogonTokenCache__<ur farm ID>



8) check if cache is available now:
                    Get-Cache | Select CacheName
should give output as below

CacheName            
---------          
DistributedAccessCache_<ur farm ID>
DistributedActivityFeedCache_<ur farm ID>
DistributedActivityFeedLMTCache_<ur farm ID>
DistributedBouncerCache_<ur farm ID>
DistributedDefaultCache_<ur farm ID>
DistributedLogonTokenCache_<ur farm ID>
DistributedSearchCache__<ur farm ID>
DistributedSecurityTrimmingCache_<ur farm ID>
DistributedServerToAppServerAccessTokenCache_<ur farm ID>
DistributedViewStateCache_<ur farm ID>


 Hope this helps