9

I'm trying to load an XML-file, located in a folder in my project (using Visual Studio 2012).

The structure is this:

solutionRoot\
-  service\
--   ServiceClass.cs
--   AppValues.xml  <-- this is the file I want to load

In my ServiceClass, I'm trying to read from the XML-file with the following code:

public String GetXmlElement(String elementName)
{
    [....]
    XDocument document = XDocument.Load(@"\service\AppValues.xml");
    [...]
}

Which gives the following error, when I'm trying to test the code:

Test method PandaTests.ServiceTest.ReadXmlCanReadXml threw exception: 
System.IO.DirectoryNotFoundException: Could not find a part of the path 
'C:\Users\MyName\Documents\GitHub\project\Project22\PandaTests\bin\Debug\service\AppValues.xml'.

It's obviously a problem with my path, but I can't figure out how to get the relative path right. I've looked at other questions here on stack overflow, but many of them seem overly involved. Is there an easy way to load the XML-file without giving an absolute path?

Tobias Roland
  • 1,182
  • 1
  • 13
  • 35

7 Answers7

16

When VS runs your program, your working directory is set to the Debug/Release folder, not to your solution root.

You have a couple options that I know of...

  1. Use an absolute path, but you don't want this
  2. Set your file to copy into your working directory on build. You do this by modifying the properties of the file in the solution explorer. Thanks to T.Roland in the comments below: Set Copy to Output Directory to Copy if Newer and set Build Action to Embedded Resource;
  3. Modify your solution's working directory to be your solution root This thread offers different ways to accomplish that.
Community
  • 1
  • 1
Tyler Lee
  • 2,736
  • 13
  • 24
  • 4
    I've suggested an edit to expand on the second point (which properties to set) basically: A) Set **Copy to Output Directory** to *Copy if Newer*; B) Set **Build Action** to *Embedded Resource*; C) The file can now be loaded with `XDocument.Load(@"service\AppValues.xml")` – Tobias Roland Nov 15 '13 at 14:20
4

I faced the same problem and solved it using "Server.MapPath"

For example,

string path=Server.MapPath("~/service/AppValues.xml");

XDocument document = XDocument.Load(path);

Hope it helps.

Sarath Rachuri
  • 2,086
  • 2
  • 18
  • 18
2

Bring up the properties in Visual Studio for AppValues.xml. Change "Copy to Output Directory" to "Copy if Newer", and build the project.

jlew
  • 10,491
  • 1
  • 35
  • 58
0

check this

XDocument document = XDocument.Load(@"..\service\AppValues.xml");
Hichem
  • 1,111
  • 11
  • 30
0

Set the build action of the xml file to be "Embedded resource" and then reference using this code

private static UnmanagedMemoryStream GetResourceStream(string resName)
{
    var assembly = Assembly.GetExecutingAssembly();
    var strResources = assembly.GetName().Name + ".g.resources";
    var rStream = assembly.GetManifestResourceStream(strResources);
    var resourceReader = new ResourceReader(rStream);
    var items = resourceReader.OfType<DictionaryEntry>();
    var stream = items.First(x => (x.Key as string) == resName.ToLower()).Value;
    return (UnmanagedMemoryStream)stream;
}

    var file = GetResourceStream("appValues.xml");
guymid
  • 1,186
  • 8
  • 11
0

When adding a file to Visual Studio project, by default it is not copied to the generated output. As such, you need to set to either copy the file or do so manually.

To set the file to automatically copy, select it in solution explorer, right click and select properties. Update the value for "Copy to Output Directory" to "Copy Always". This will ensure a copy of the file is available at runtime in a subfolder of the resultant solution.

You can then load the file using something like:

string path = System.Io.Path.Combine(Application.StartupPath, @"\service\AppValues.xml");
XDocument doc = XDocument.Load(path);
Kami
  • 19,134
  • 4
  • 51
  • 63
  • When I try to use the `Application.StartupPath`, StartupPath gives a compile error - it doesn't seem to be a parameter of Application. What should I be `using` to get it to work? – Tobias Roland Nov 13 '13 at 15:49
  • @T.Roland The Application.StartupPath is a property to identify where the application is, and thereby determine the relative paths. You can try `AppDomain.CurrentDomain.BaseDirectory` or any of the suggestions at http://stackoverflow.com/questions/6041332/best-way-to-get-application-folder-path as alternatives. – Kami Nov 13 '13 at 17:25
0

I solved it in 2 steps. I'm using MVC and I had to use this in a class file.

1) String path

=HttpContext.Current.Server.MapPath("~/App_Data/yourxmlfilename.xml");
XDocument doc = XDocument.Load(path);

2) Change XML file properties

Build Action: Content
Copy to Output Directory: Copy always