views:

98

answers:

1

So a bit of an overview around the lead up to this exception.

I've created a website on my dev machine (windows xp, asp.net 4) and targeted it to .Net 3.5. I then deployed the 100% working website on the stage machine (Windows 7, ASP.net 2, IIS 7.5).

After sorting out numerous security problems, I've come to a stop at this bewildering exception, which although I clearly understand what it means, I can't fathom why this exception would be coming from the line mentioned in the stack trace.

...Which is where you lot come in! :)

So the stack trace:

[NullReferenceException: Object reference not set to an instance of an object.]
   DVL.Ruby.Admin.Config.ConfigManager..ctor(String path) in C:\Documents and Settings\Andy\Desktop\SS_DVL\Displays\Ruby.root\Ruby\Ruby.Admin\Config\ConfigManager.cs:41
   DVL.Ruby.Admin.SettingGroups.Page_Load(Object sender, EventArgs e) in C:\Documents and Settings\Andy\Desktop\SS_DVL\Displays\Ruby.root\Ruby\Ruby.Admin\SettingStates.aspx.cs:33
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +50
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

ConfigManager.cs

namespace DVL.Ruby.Admin.Config
{
    public class ConfigManager
    {
        private XElement m_appSettings;
        private XElement m_appMappings;
        private XElement m_appConnectionStrings;

        private List<Setting> m_settings;
        private List<ConnectionString> m_connectionStrings;

        private string m_path;

        private ConfigManager() { }

        private ConfigManager(string path)
        {
            if (path==null)
            {
                throw new NullReferenceException("The web.config path provided cannot be null.");
            }

            if (File.Exists(path)==false)
            {
                throw new ArgumentException("The web.config file does not exist.");
            }

            // Load the file
            XDocument configDocument = XDocument.Load(path);
            m_path = path; // <-- Line 41

      // Do some stuff...
        }

        /// <summary>
        /// Creates and returns a new instance of the ConfigManager
        /// </summary>
        /// <param name="path">The path of the web.config file to load.</param>
        /// <returns>A new instance of the ConfigManager</returns>
        public static ConfigManager Load(string path)
        {
            return new ConfigManager(path);
        }

SettingStates.aspx.cs

namespace DVL.Ruby.Admin
{
    public partial class SettingGroups : System.Web.UI.Page
    {
        ConfigManager m_configManager;
        List<State> m_states;

        protected void Page_Load(object sender, EventArgs e)
        {
            // Check we have the location of the web.config file we'll be editing
            string webConfigPath = WebConfigurationManager.AppSettings[Constants.ApplicationKey_WebConfigPath];
            if (webConfigPath == null)
            {
                return;
            }

            try
            {
                // Initialise the manager
                m_configManager = ConfigManager.Load(webConfigPath); // <-- Line 33
            }
            catch (ConfigurationException ex)
            {
                ErrorMessage.Visible = true;
                ErrorMessage.Text = ex.Message;
                SaveStateButton.Enabled = false;
                LoadStateButton.Enabled = false;
                return;
            }

So as you can see, the null reference is occurring at this line:

m_path = path;

Which is odd, because i check if path is null (not that it'd make a difference) and m_path is already null but that doesn't matter as I'm assigning!

One thing I noticed when looking at the library in reflector is that the compiled version changes to:

this.m_path = path;

Which I guess gives a logical point at which is may be failing (i.e. the 'this' reference). But why would this be null? Is it something to do with my static Load(string) method creating the object instance? If so, why does it work on my dev pc and not the deployment machine?

I'm quite happy to just have a normal constructor for the object, but I was just following how Microsoft have developed their APIs (ala XDocument). I tried to use reflector again to see if they're implementing their load method differently but the method was empty (maybe obfuscated?).

Anyway, lets wrap up, so the main questions:

  • Why is it failing on line 41?
  • Why does is not occur on my dev machine?
A: 

Ok,

So basically, possibly a noob mistake. The website was compiled in Release, which I'm guessing means it doesn't contain all the debug information, as it was the line number that was wrong (line 41 should have been pointer further into the constructor where a more understandable problem to do with config occured).

All's well and good, but it bugs me a little. Are ASP.net compiles in release different to console or other applications? I'm sure I've got a stack trace with correct lines from a Release before?

Also, why are the line numbers correct further down the stack trace? i.e. Line 33 was correct. Was this just pure coincidence?

Ta!

Andy.

Andy