Hi folks
Sorry about this long query, but I fear it is a bit complicated, and I want to present all the facts. I have a module that generates a NullReferenceException when I try to add it to a page. It does this in a new install of DNN 6.0.2, but it has been doing it for a few previous versions, but now I really want to get it sorted. It is definitely my module causing the issue, as I can add other core modules OK. I think it is some sort of database access issue, but it is evidently not a standard database corruption issue, as the problem is evident even with the new database created for the new install. I've followed the debugger through the ModuleController class in the DotNetNuke.Entities.Modules source code, and although I reckon I found the reason for the problem, I'm not sure how to go about fixing it. This means I need to try and explain it, unfortunately this means a rather lengthy explanation about which code throws the exception. I have broken it down into 8 stages! Here goes ...
1. At the end of this explanation, I will end up back here in the Module Controller class, at the AddModule(ModuleInfo module) method, with the exception thrown because tmpModule is still Null despite the call to GetModule:
if (module.TabModuleID == -1)
{
if (tmpModule == null)
{
tmpModule = GetModule(module.ModuleID, module.TabID);
}
module.TabModuleID = tmpModule.TabModuleID;
}
2. GetModule is called with the moduleID and tabID values:
public ModuleInfo GetModule(int moduleID, int tabID)
{
return GetModule(moduleID, tabID, false);
}
3. From within GetModule, dataProvider.GetModule(moduleID, tabID) is called:
if (ignoreCache || !bFound)
{
modInfo = CBO.FillObject<ModuleInfo>(dataProvider.GetModule(moduleID, tabID));
}
return modInfo;
4. The IDataReader object is returned from SqlHelper.ExecuteReader:
public override IDataReader GetModule(int ModuleId, int TabId)
{
return SqlHelper.ExecuteReader(ConnectionString, DatabaseOwner + ObjectQualifier +
"GetModule", ModuleId, GetNull(TabId));
}
5. The IDataReader object is used to 'CreateObjectFromReader'. At this stage the IDataReader dr appears as it should be to my inexperienced eyes, e.g.: dr.Depth is still set to 0, before the query takes place:
public static TObject FillObject<TObject>(IDataReader dr)
{
return (TObject) CreateObjectFromReader(typeof (TObject), dr, true);
}
6. CreateObjectReader is called with the IDataReader object, and closeReader set to True, and so it ends up at the Read call shown with [//1], but the result of this call is that the dr properties are filled with InvalidOperationException exceptions, and the code arrives at [//2] with no object to be returned as objObject:
private static object CreateObjectFromReader(Type objType, IDataReader dr, bool closeReader)
{
object objObject = null;
bool isSuccess = Null.NullBoolean;
bool canRead = true;
if (closeReader)
{
canRead = false;
//read datareader
if (dr.Read()) //1
{
canRead = true;
}
}
try
{
if (canRead)
{
//Create the Object
objObject = CreateObject(objType, false);
//hydrate the custom business object
FillObjectFromReader(objObject, dr);
}
isSuccess = true;
}
finally
{
//Ensure DataReader is closed
if ((!isSuccess))
{
closeReader = true;
}
CloseDataReader(dr, closeReader);
}
return objObject; //2
}
7. So at this stage the object objObject is still Null, and the IDataReader is snafu-ed, with the following complement of properties:
dr Depth property shows an error:
dr.Depth threw an exception of 'System.InvalidOperationException'
dr.FieldCount threw an exception of 'System.InvalidOperationException'
dr.Rows threw an exception of 'System.InvalidOperationException'
dr.VisibleFieldCount threw an exception of 'System.InvalidOperationException'
dr.IsClosed = True
dr.RecordsAffected = -1
dr.ResultsView = Invalid attempt to call FieldCount when reader is closed
I think it is this last error in ResultsView that is the key to understanding what has gone wrong.
8. The empty/Null objObject is then of course passed back up through the code to arrive back via the modInfo object to become tmpModule, where the method has to throw a 'System.NullReferenceException' exception because tmpModule is a Null reference at this line:
module.TabModuleID = tmpModule.TabModuleID;
The exception of course being:
***************************
An exception of type 'System.NullReferenceException' occurred in DotNetNuke.DLL but was not handled in user code
Additional information: Object reference not set to an instance of an object.
******************************
So after all this, my question is:
Why does the dr.Read call fail? What in the module could cause this? The module appears to install OK, with no errors generated in the UI or the EventLog, but what should I be looking for? How can I debug the relevant SQL query, given that the debugger doesn't allow me to step into any T-SQL?
Can anybody help?
Regards
|