Thursday, February 6, 2014

How can you use PortalSiteMapProvider to query SharePoint List Items. Through Console or Webparts.

Sometimes we need to query some Items from a SharePoint List which data is not changing so frequently. In this case we need to add values of these list Items into cache. For that we need to add it manually to our cache. And also need to add an event receiver in case of any change in data to refresh cache. However SharePoint provides  "PortalSiteMapProvider" class to load this set of queried items in cache and refresh in case of changes. Here is the way to use this, hope it helps :

For a console application as we will not get HttpContext. So we need to create one as highlighted part otherwise you will get PortalWebSiteMapNode object null :

public static void GetConfigListItemsThroughConsole(string strValue1, string strValue2)
        {
            try
            {
                // Get the current SPWeb object. 
                using (SPSite objSPSite = new SPSite("http://servername:portno/sites/sitename"))
                {
                    using (SPWeb curWeb = objSPSite.OpenWeb())
                    {

                        // Create the query. 
                        SPQuery curQry = new SPQuery();
                        curQry.Query = string.Format("<Where><And><Eq><FieldRef Name='Column1' /><Value Type='Text'>{0}</Value></Eq><Eq><FieldRef Name='Column2' /><Value Type='Text'>{1}</Value></Eq></And></Where>", strValue1, strValue2);

                        // Create an instance of PortalSiteMapProvider. 
                        PortalSiteMapProvider ps = PortalSiteMapProvider.WebSiteMapProvider;

                        if (HttpContext.Current == null)
                        {
                            HttpRequest request = new HttpRequest("", curWeb.Url, "");
                            HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
                            HttpContext.Current.Items["HttpHandlerSPWeb"] = curWeb;
                        }
                        SPWeb curWeb2 = SPControl.GetContextWeb(HttpContext.Current);

                        PortalWebSiteMapNode pNode = ps.FindSiteMapNode(curWeb2.ServerRelativeUrl) as PortalWebSiteMapNode;
                       
                        // Retrieve the items. 

                        SiteMapNodeCollection pItems = ps.GetCachedListItemsByQuery(pNode, "ListName", curQry, curWeb);

                        // Enumerate through all of the matches. 
                        foreach (PortalListItemSiteMapNode pItem in pItems)
                        {
                            Console.WriteLine(Convert.ToString(pItem["Title"]));
                            Console.ReadLine();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Occured :" + ex.Message.ToString());
                Console.ReadLine();
            }

        }
Just call this method from any windows or console application event.

Now, For a SharePoint as we will have HttpContext here :

public static string GetConfigListItemsThroughWP(string strValue1, string strValue2)
       {
           string resultValue = string.Empty;
           try
           {
              
               // Get the current SPWeb object. 
               SPWeb curWeb = SPControl.GetContextWeb(HttpContext.Current); 


                       // Create the query. 
                       SPQuery curQry = new SPQuery();
                       curQry.Query = string.Format("<Where><And><Eq><FieldRef Name='Column1' /><Value Type='Text'>{0}</Value></Eq><Eq><FieldRef Name='Column2' /><Value Type='Text'>{1}</Value></Eq></And></Where>", strValue1, strValue2);

                       // Create an instance of PortalSiteMapProvider. 
                       PortalSiteMapProvider ps = PortalSiteMapProvider.WebSiteMapProvider;

                       //PortalSiteMapProvider ps = PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode;

                      
                       PortalWebSiteMapNode pNode = ps.FindSiteMapNode(curWeb.ServerRelativeUrl) as PortalWebSiteMapNode;
                       //PortalWebSiteMapNode pNode = ps.FindSiteMapNode(curWeb.Url) as PortalWebSiteMapNode;
                       // Retrieve the items. 

                       System.Web.SiteMapNodeCollection pItems = ps.GetCachedListItemsByQuery(pNode, "ListName", curQry, curWeb);

                       // Enumerate through all of the matches. 
                       foreach (PortalListItemSiteMapNode pItem in pItems)
                           {
                              resultValue =  Convert.ToString(pItem["Title"]);
                           
                           }
                       }
                       catch (Exception ex)
                       {
               
                       }
           return resultValue;

       }

Here we do not need to create a HttpContext, all we need to do to call this method from any webpart/SharePoint event.