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.
    – Abhi
    Commented Nov 27, 2017 at 13:43
  • And which device presentation you're planning to index?
    – Marek Musielak
    Commented Nov 27, 2017 at 13:44
  • We are planning to Index Default Device presentation data source content only.
    – Abhi
    Commented Nov 27, 2017 at 13:46
  • Which database are the GetItemContent and GetDataSourceContent methods using? Commented Nov 27, 2017 at 13:51
  • GetItemContent ,GetDataSourceContent methods are implemented in local class itself processing logic . These methods are using web database .
    – Abhi
    Commented Nov 27, 2017 at 14:15

2 Answers 2


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.
    – Abhi
    Commented Nov 27, 2017 at 17:18
  • We will try with this approach . I think this will solve our problem.
    – Abhi
    Commented Nov 28, 2017 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.
    – Abhi
    Commented Nov 28, 2017 at 5:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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