We are using Lucene Index for our site search, our objective is to add all the content which is associated with Page Item.
Here we have added Two custom index field for 1) "PageContent" and 2 )"PageUrl" to hold data.
"PageContent" field is being populated with Current Page Item data and the presentation item data source.
But we are getting the error while reading presentation component DataSource Item, It is throwing the null exception on item.Visualization.
Environment - Sitecore 8.1 Update 3
Items to Crawl - All the item which is coming under the Home Node.

Any suggestion will be helpful.

Code -

 public object ComputeFieldValue(IIndexable indexable)
        {
            var fieldValue = (object)null;
            var item = (Item)(indexable as SitecoreIndexableItem);

            if (item.Visualization.Layout != null)
            {
                var itemContent = this.GetItemContent(item);
                var dataSourceContent = this.GetDataSourceContent(item);
                fieldValue = StringUtil.RemoveTags("{0} {1}".FormatWith(itemContent, dataSourceContent));
            }

            return fieldValue;
        }

Stack Trace -

at Sitecore.CES.DeviceDetection.Rules.RuleDeviceInformationManager.GetUserAgentFromDeviceRuleContext(DeviceRuleContext deviceRuleContext)
   at Sitecore.CES.DeviceDetection.Rules.RuleDeviceInformationManager.ResolveObject[T](RuleContext ruleContext, String key, Func`2 objectFactory, String trackerDisabledMessageFormat, String deviceDetectionExceptionMessageFormat, Object[] formatArgs)
   at Sitecore.CES.DeviceDetection.Rules.RuleDeviceInformationManager.GetDeviceInformation(RuleContext ruleContext)
   at Sitecore.CES.DeviceDetection.Rules.Conditions.DeviceTypeCondition`1.Execute(T ruleContext)
   at Sitecore.Rules.Conditions.WhenCondition`1.Evaluate(T ruleContext, RuleStack stack)
   at Sitecore.Rules.Conditions.OrCondition`1.Evaluate(T ruleContext, RuleStack stack)
   at Sitecore.Rules.Conditions.OrCondition`1.Evaluate(T ruleContext, RuleStack stack)
   at Sitecore.Data.Items.DeviceItem.MatchesRules(HttpContextBase httpContext, SafeDictionary`2 customData)
   at Sitecore.Data.Items.DeviceItem.FindBestMatch(Database database, HttpContextBase httpContext)
   at Sitecore.Data.Items.DeviceItem.ResolveDevice(Database database, HttpContextBase httpContext)
   at Sitecore.Data.Items.ItemVisualization.ResolveContextDevice()
   at Sitecore.Data.Items.ItemVisualization.get_Layout()

//This Method will read the current item content 
    public string GetItemContent(Item item){
    //
    //logic to get the current item content 
    }


GetItemContent(Item item)

 public string GetItemContent(Item item){
    logic to get the current item content 
    }


GetDataSourceContent(Item item);


This method will read the data source of all presentation item , contact the filed data and return the data.

  public string  GetDataSourceContent(Item item)
{
     string data=string.empty;
     var device = DeviceItem.ResolveDevice(item.Database);
     var renderings = item.Visualization.GetRenderings(device, false).ToList();

     return data
     }
  • FYI - We are using Sitecore device detection rules in our item to show different presentation. – Abhimanyu Singh Nov 27 '17 at 13:43
  • And which device presentation you're planning to index? – Marek Musielak Nov 27 '17 at 13:44
  • We are planning to Index Default Device presentation data source content only. – Abhimanyu Singh Nov 27 '17 at 13:46
  • Which database are the GetItemContent and GetDataSourceContent methods using? – Nathan Hase Nov 27 '17 at 13:51
  • GetItemContent ,GetDataSourceContent methods are implemented in local class itself processing logic . These methods are using web database . – Abhimanyu Singh Nov 27 '17 at 14:15
up vote 2 down vote accepted

An alternative way to get list of datasource items referenced to the current item is to use the Link database, Here is an example:

//Get all the datasource items by filtering the item referneces
var itemLinks = Sitecore.Globals.LinkDatabase.GetReferences(item)
                .Where(r => (r.SourceFieldID == Sitecore.FieldIDs.LayoutField 
                    || r.SourceFieldID == Sitecore.FieldIDs.FinalLayoutField) && r.TargetDatabaseName == item.Database.Name);

//Null check and filter any duplicate datasource items
return itemLinks.Select(l => l.GetTargetItem()).Where(i => i != null).Distinct().ToArray();

This example is working on Sitecore 8.2 - Update 3

  • Yes, this is one of alternate approach to get the referenced item. The accuracy depends on link database and broken link issues may impact results. I tried this approach for some smaller problems and observed some performance issues as well . In The current issue we are dealing with index.. we will try this also , may be this can resolve our issue. – Abhimanyu Singh Nov 27 '17 at 17:18
  • We will try with this approach . I think this will solve our problem. – Abhimanyu Singh Nov 28 '17 at 5:51

I think the issue is when you try to resolve the device. Rather than use DeviceItem.ResolveDevice - you know you want the default device, so you can just get that directly. Like this:

public string GetDataSourceContent(Item item)
{
    string data = string.Empty;
    var deviceItem = item.Database.GetItem("{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3}");
    var device = new DeviceItem(deviceItem);
    var renderings = item.Visualization.GetRenderings(device, false).ToList();

    return data;
}

{FE5D7FDF-89C0-4D99-9AA3-B5FBD009C9F3} is the guid of the default device item in Sitecore.

This way would be slightly better performing too as it doesn't not have to run an entire pipeline to resolve a device that you already know you want.

  • We had tried with this but the exception comes when we write item.Visualization. – Abhimanyu Singh Nov 28 '17 at 5:54

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.