Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Relative Paths in Referenced Libraries

Tags:

c#

path

asp.net

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.

like image 867
dnewcome Avatar asked Apr 28 '09 16:04

dnewcome


1 Answers

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) 
    );
...
like image 71
Joe Avatar answered Sep 20 '22 21:09

Joe