另一个空引用异常
我知道空引用异常通常总是模糊的,任何数量的东西都可以产生它,但我在这里没有想法了......发生的事情是当我尝试单击食谱类别链接时我收到此错误:
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
我不能但不知道什么被处理为空。以下是来自 SearchManager.cs 的代码以及错误消息引用的 GetRecipes 方法。数据全部存在于数据库中,任何内容都不应该为空。在我升级该项目所依赖的程序集之前,它曾经一度工作过。唯一改变的是程序集使用 int64 而不是 int,但为了构建该死的项目,我必须将它们转换为 int。但在这种情况下我想这应该不重要。我不知道我在这里抓住了空气。
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;
}
}
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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要添加大量错误处理代码。没有单一的“if (x != null)”或“if (x == null)”类型的语句。您需要重写所有代码以更具防御性。
是的,要找到这个特定的错误,您需要单步调试您的程序。看看它在哪里爆炸。但是如果你解决了这个问题,除非你添加了大量的错误检查代码,否则无法保证你的代码不会在 5 分钟后在其他地方崩溃。
看起来您正在整个方法中调用外部代码。基本上,您需要验证从中返回的所有内容,看起来您相信外部代码始终返回有效数据。
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.
如果不在那里并能够深入研究您的代码,这几乎是不可能的。我可以告诉您要做的是查找为空的子对象。例如,假设您有一个 Car 对象:
在代码中的某个时刻,您执行类似...
Car car = new Car(); 的
操作然后你去某个地方使用它,在你的代码中,有些东西尝试访问 Passenger 的属性,但 Passenger 是 NULL。问题是,在更高的层面上,当你查看 Car 时,你会看到 car 不为空,所以你认为它没问题。理解?
所以...检查你的复杂对象是否有空值,看看它在哪里。顺便说一句,如果您在代码中尝试...catch 广泛定义的语句,它们会非常好地导致这种错误并使其很难找到...
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:
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...
为什么不在函数顶部设置一个中断并逐步调试并检查变量呢?这是找出空引用异常原因的最简单方法。
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.