Question

I understand that Null Reference exceptions are always generally vague and any number of things can produce it but I'm running out of ideas here... Whats happening is when I try to click on a recipe category link im getting this error:

NullReferenceException: Object reference not set to an instance of an object.
Company.BusinessLayer.Recipes.SearchManager.GetRecipes(Int64 folderId, String searchTerm, Int32 pageIndex, Int32 pageSize, Int32& categoryCount, Int32& pageCount) +1020
TargetInvocationException: Exception has been thrown by the target of an invocation.
Comapny.Website.Controls.Recipes.CategoryControl.ods_Selected(Object sender, ObjectDataSourceStatusEventArgs e) +940


System.Web.UI.WebControls.ObjectDataSourceView.OnSelected(ObjectDataSourceStatusEventArgs e) +103
   System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(ObjectDataSourceMethod method, Boolean disposeInstance, Object& instance) +431
   System.Web.UI.WebControls.ObjectDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +1953
   System.Web.UI.WebControls.BaseDataList.GetData() +56
   System.Web.UI.WebControls.DataList.CreateControlHierarchy(Boolean useDataSource) +177
   System.Web.UI.WebControls.BaseDataList.OnDataBinding(EventArgs e) +64
   System.Web.UI.WebControls.BaseDataList.DataBind() +55
   Company.Website.Controls.Recipes.CategoryControl.OnPreRender(EventArgs e) +138
   System.Web.UI.Control.PreRenderRecursiveInternal() +103
   System.Web.UI.Control.PreRenderRecursiveInternal() +175
   System.Web.UI.Control.PreRenderRecursiveInternal() +175
   System.Web.UI.Control.PreRenderRecursiveInternal() +175
   System.Web.UI.Control.PreRenderRecursiveInternal() +175
   System.Web.UI.Control.PreRenderRecursiveInternal() +175
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2496

I cant't figure out what is be processed as null though. here is the code from SearchManager.cs and the GetRecipes Method the error message references. The data is all there in the database and nothing should be null. It was working at one time before I upgraded the assemblies this project relies on. The only thing that has changed is that the assemblies use int64 instead of int but to get the damn project to build i had to cast them into int's. It shouldn't matter though in this situation I would think. I don't know I'm grasping at air here.

public ContentBase[] GetRecipes(long folderId, string searchTerm, int pageIndex, int pageSize, out int categoryCount, out int pageCount)
{
    ContentBase[] mergedResultset = null;

    IndexSearch idx = new IndexSearch();

    idx.XmlConfigId = 8;
    idx.FolderId = folderId;
    idx.Recursive = true;


    // if a search term is provided, search this term
    if (!string.IsNullOrEmpty(searchTerm))
    {
        searchTerm = searchTerm.Replace("'", "''");

        // INDEX SEARCH BASED ON INGREDIENTS
        Ektron.Cms.Controls.IndexSearch.SearchPram paramTerm = new Ektron.Cms.Controls.IndexSearch.SearchPram();
        paramTerm.DataType = Ektron.Cms.Common.EkEnumeration.XMLDataType.String;
        paramTerm.SearchType = Ektron.Cms.Common.EkEnumeration.XMLSearchRangeType.Contains;
        paramTerm.XPath = "/root/Ingredients";
        paramTerm.Value1 = searchTerm;
        idx.AddParm(paramTerm);

        idx.Search();
        mergedResultset = (ContentBase[])idx.EkItems;

        // CUSTOM SEARCH BASED ON TITLE
        FolderData[] childFolders = GetChildFolders(folderId, true);

        // Search based on title
        Ektron.Cms.API.Search.SearchManager search = new Ektron.Cms.API.Search.SearchManager();
        Ektron.Cms.ContentSearchCondition conditionAll = new Ektron.Cms.ContentSearchCondition();
        conditionAll.setType = EkEnumeration.SearchType.AND;

        ContentSearchCondition condFolderIds = new ContentSearchCondition();
        // add condition folder Id for current folder and for each sub folder
        condFolderIds.setType = EkEnumeration.SearchType.OR;
        AddFolderIdCondition(condFolderIds, folderId);
        foreach (FolderData fd in childFolders)
        {
            AddFolderIdCondition(condFolderIds, fd.Id);
        }
        conditionAll.AddCondition(condFolderIds);

        ContentSearchCondition condTerm = new ContentSearchCondition();
        condTerm.setType = EkEnumeration.SearchType.LIKE;
        condTerm.setValue = searchTerm;
        condTerm.setVariable = "content.content_title";
        conditionAll.AddCondition(condTerm);

        ContentSearchCondition condType = new ContentSearchCondition();
        condType.setType = EkEnumeration.SearchType.EQUAL;
        condType.setValue = 8;
        condType.setVariable = "content.xml_config_id";
        conditionAll.AddCondition(condType);

        ContentData[] contents = search.Execute(conditionAll);


        mergedResultset = MergeResultsets(idx.EkItems, contents, "/Recipes/Detail.aspx");

        // rewrite all quicklinks with url alias
        IDictionary<int, string> aliases = new UrlAliasApi().GetUrlAliasesByType(Company.DataLayer.Enumeration.UrlAliasType.Recipe);
        foreach (ContentBase recipe in mergedResultset)
        {
            // if alias exists, overwrite quicklink!
            string alias;
            if (aliases.TryGetValue((int)recipe.Id, out alias))
            {
                recipe.QuickLink = alias;
            }
        }

    }
        // otherwise search based without parameter (fake param)
    else
    {
        // if category recipes not already in cache, get them through ektron, otherwise, just get them from cache
        if (RecipeCategoryCache.Current.Categories.ContainsKey((int)folderId) && RecipeCategoryCache.Current.Categories[(int)folderId] != null && RecipeCategoryCache.Current.Categories[(int)folderId].Length > 0)
        {
            mergedResultset = RecipeCategoryCache.Current.Categories[(int)folderId];
        }
        else
        {
            Ektron.Cms.Controls.IndexSearch.SearchPram param = new Ektron.Cms.Controls.IndexSearch.SearchPram();
            param.DataType = Ektron.Cms.Common.EkEnumeration.XMLDataType.Boolean;
            param.SearchType = Ektron.Cms.Common.EkEnumeration.XMLSearchRangeType.True;
            param.XPath = "/root/Viewable";
            idx.AddParm(param);

            idx.Search();
            mergedResultset = (ContentBase[])idx.EkItems;

            // rewrite all quicklinks with url alias
            IDictionary<int, string> aliases = new UrlAliasApi().GetUrlAliasesByType(Company.DataLayer.Enumeration.UrlAliasType.Recipe);
            foreach (ContentBase recipe in mergedResultset)
            {
                // if alias exists, overwrite quicklink!
                string alias;
                if (aliases.TryGetValue((int)recipe.Id, out alias))
                {
                    recipe.QuickLink = alias;
                }
            }

            RecipeCategoryCache.Current.Categories[(int)folderId] = mergedResultset;
        }
    }

    categoryCount = mergedResultset.Length;

    // if page size provided is 0, No paging,
    // if more than 0, calculate paging
    if (pageSize > 0 && mergedResultset.Length > 0)
    {
        PagingHelper pgHelper = new PagingHelper();
        pgHelper.CalculatePagingInfo(pageIndex, categoryCount, pageSize);

        pageCount = pgHelper.NumberOfPages;

        List<ContentBase> lst = new List<ContentBase>();

        for (int i = pgHelper.StartIndex; i < pgHelper.EndIndex; i++)
        {
            lst.Add(mergedResultset[i]);
        }

        return lst.ToArray();

    }
    else
    {
        pageCount = 1;
        return mergedResultset;
    }

}
Was it helpful?

Solution

Without being there and being able to dig into your code, this ones almost impossible. What I can tell you to do is look for sub objects that are null. For example, let's say you have a Car object:

class Car(){
string Color;
string Make;
string Model;
Passenger passenger; // Passenger is a another object defined elsewhere
}

And at some point in your code, you do something like...

Car car = new Car();

Then you go to use it somewhere, and down the road in your code, something tries access a property of Passenger, but Passenger is NULL. The problem is, at a higher level, when you look at Car, you see car is NOT null, so you think it is OK. Understand?

So... check your complex objects for nulls, and see where it gets ya. BTW, if you try...catch statements in your code that are broadly defined, they are marvelous at causing this kind of error and making it hard to find...

OTHER TIPS

You need to add a TON of error handling code. There is not a single "if (x != null)" of "if (x == null)" type of statement. You need to rewrite all your code to be more defensive.

And yes, to find this specific error, you need to step through your program. and see where it blows up. But if you fix this one problem, unless you add a lot of error checking code, there is no guarantee your code will not blow up 5 minutes later somewhere else.

It looks like you are calling outside code throughout this method. Basically you need to validate everything you get back from it, it looks like you are trusting the outside code to always return valid data.

Why don't you set a break at the top of the function and debug it step by step and check variables? It's the easiest way to figure out what is the reason of null reference exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top