tags:

views:

816

answers:

2

I have an ASP.NET website in which I am loading some validation rules from an xml file. This xml file name, with no path info, is hard coded in a library. (I know that the hard coded name is not good, but let's just go with it for this example).

When I run the website, ASP.NET tries to find the xml file in the source path, where the C# file in which name is hard coded is. This is completely mind boggling to me, as I can't fathom how, at runtime, we are even considering a source path as a possibility for resolving an unqualified filename.

// the config class, in C:\temp\Project.Core\Config.cs
public static string ValidationRulesFile {
   get { return m_validationRulesFile; }
} private static string m_validationRulesFile = "validation_rules.xml";

// using the file name
m_validationRules.LoadRulesFromXml( Config.ValidationRulesFile, "Call" );

Here is the exception showing the path we are looking in is the same as Config.cs:

  Exception Details: System.IO.FileNotFoundException: 
Could not find file 'C:\temp\Project.Core\validation_rules.xml'.

Can anyone explain this to me? I already know how you are supposed to handle paths in general in ASP.NET so please don't respond with solutions. I just really want to understand this, since it really surprised me, and It is going to bother me to no end.

UPDATE

Here is the relevant code for LoadRulesFromXml

public void LoadRulesFromXml( string in_xmlFileName, string in_type ) 
{    
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load( in_xmlFileName );
...

UPDATE2

It looks like the Cassini web server gets its current directory set by VS, and indeed it is set to the path of my library project. I'm not sure exactly how VS determines which project to use for the path, but this at least explains what is happening. Thanks Joe.

+2  A: 

At a complete guess I would say that the Method LoadRulesFromXml() is looking at the path of the Application Root URL for where the site is hosted... which is C:\temp\Project.Core\ probably by doing a Server.MapPath("~")

Can you post the code for LoadRulesFromXML or do you have that code ?

Eoin Campbell
The site root in this case would be something like C:\temp\Project.UI.Web. This is why I can't understand why we would be looking off to the side at a location that is not even under the web root. BTW it is the ASP.NET development web server that is serving the site, and the site and the library are under the same solution, but in parallel directories.
dnewcome
+3  A: 

If you don't supply a path, then file access will normally use the current working directory as the default. In ASP.NET this is probably your web application directory.

It's not usually a good idea to rely on the current working directory, so you can use Path.Combine to specify a different default directory, e.g. one relative to AppDomain.CurrentDomain.BaseDirectory, which is also the web application directory for an ASP.NET app.

You should add the path explicitly to the name of the file you're opening. You could also try tracing the current working directory.

When running Cassini from Visual Studio, the current directory is inherited from whatever happens to be Visual Studio's working directory: this seems to be your case.

I.e.:

public void LoadRulesFromXml( string in_xmlFileName, string in_type ) 
{   
    // To see what's going on
    Debug.WriteLine("Current directory is " +
              System.Environment.CurrentDirectory);    

    XmlDocument xmlDoc = new XmlDocument();    

    // Use an explicit path
    xmlDoc.Load( 
       System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
       in_xmlFileName) 
    );
...
Joe
The current directory is why I am confused. If we go by the current directory logic we would be under the site somewhere, not off in the code for some library that we reference that is not even under the site root.
dnewcome
I am running the site using Cassini, so possibly some path is being inherited from VS as you mentioned.
dnewcome