I have a solution containing two projects. One project is just for doing all data stuff and the other one, the startup project, do all the web stuff.
Now I want to get the TasksDataBase.xml from the TaskManagerHelpers class by first getting the projects root directory. But all I get is the TaskManager.Web root directory. (I call the method inside TaskManagerHelpers.cs from a controller inside TaskManager.Web)
How do I get the TaskManager.Data root directory when I'm in a class in the same project?
I've tried with theese methodes and similar ones.
HttpContext.Current.Request.PhysicalApplicationPath;
System.IO.Path.GetFullPath();
AppDomain.CurrentDomain.BaseDirectory;
Thanks in advance!
One possibility is to embed the XML file into the assembly of the class library and then read it as resource in your web application. Remember that when you publish your web application to a web server all that will get into the package will be the files of this web application. There's no physical relation to some projects that might have lived into the Visual Studio solution that this web application was part of.
You may take a look at the GetManifestResourceStream method which will allow you to read the embedded XML from the referenced assembly.
Here's an example:
// you could use any type from the assembly here
var assembly = typeof(TaskManagerHelper).Assembly;
using (var stream = assembly.GetManifestResourceStream("TaskManager.Data.DataBase.TasksDataBase.xml"))
using (var xmlReader = XmlReader.Create(stream))
{
// ... do something with the XML here
}
Bear in mind though that since the file is embedded into the assembly you will not be able to modify it. It is readonly. If you need to modify it then an alternative approach would consist into copying this file to your web application. For example a good place is the App_Data special folder. You could even setup a post compilation step that will copy the XML file in this location.
And then you can reference it easily:
string xmlFile = HostingEnvironment.MapPath("~/App_Data/TasksDataBase.xml");
using (var xmlReader = XmlReader.Create(xmlFile))
{
// ... do something with the XML here
}
In this case since the XML file is now physically part of the web application and lives on the hard drive you could also modify it.
Just because the two projects are located in the same folder tree during development, says nothing about where they'll be located at run time. It's entirely possible that that could be on different machines.
"No," you say. They'll will definitely be on the same machine in the same c:\inetpub tree. That may be true, but that's your policy, not a requirement.
If you are going to establish a hard policy about where they are located, then you can hard-code that into you code.
Right-click the XML file and select properties, then change the Copy to Output Director to one of the other settings than "Do Not Copy". That will place the file into your \bin\ folder alongside the other project output. You can then use AppDomain.CurrentDomain.BaseDirectory as your base path
IF you are running a web project, all the referenced dll files are copied to the bin directory (unless they are in the GAC) and used from there, no matter if you add a reference to another project, Visual Studio first compile it and then copies it to the bin folder of the web project. You can mark your xml file as Content (Compilation Action) and with the copy always option so it always copy it to the bin directory .... the problem is that it sometime look for this files outside of the bin folder but I think that you can handle this.
Related
I have a seemingly basic question, but I can't access a folder inside my project (actually, it is a project that is one of the references of the main project), which is a folder called "pdfs" that contains 1 PDF that I want to convert to base64.
I put the "pdfs" folder in the same level of the file from where I call it, as I thought it would be easier to access (actionDB.cs file, which is in services/actions/actionDB.cs). The "pdfs" folder is in services/actions/pdfs).
But there is no way to get the correct path of this folder.
On the contrary, if I put the folder in c: , getting path = "c:\\pdfs", and the pdf file there, I can easily find it and convert the pdf perfectly in the code.
Any idea how to access these folders that are inside the projects, as if they were assets? I already put 'copy always: to the destination' and 'type of compilation: content' in the pdf properties, but I still can't access it.
I have already tried the following options:
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), #"pdfs");
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), #"services\actions\pdfs");
string path = Path.Combine(Path.GetDirectoryName(Environment.CurrentDirectory), #"services\actions\pdfs");
The namespace of the actionsDB is ProjectName.Data.services.actions.
I got results such as IIS/.., or other paths inside VS installation…, Assembly and some weird hashes.
Nothing works...
Could you help me with this?
Thank you very much,
CBD
AppDomain.CurrentDomain.BaseDirectory is probably the most useful for accessing files whose location is relative to the application install directory.
While running my project using Visual Studio, the working directory (AppDomain.CurrentDomain.BaseDirectory) is {ProjectDirectoryPath}\bin\Debug\netcoreapp2.0; but while running the project from its publish folder (after publishing it), the working directory is {PublishDirectoryPath}. All project configuration and data files are located under {ProjectDirectoryPath} and {PublishDirectoryPath} in the same tree structure. What it means is that whenever I'm running the project using Visual Studio, I should prefix the path of each of the files with ../../../.
My current solution is using the following function whenever accessing a file in the project directory:
public static string Root()
{
string root = AppDomain.CurrentDomain.BaseDirectory;
if (root.EndsWith("Debug\\netcoreapp2.0\\"))
root = root + Slash("../../..");
return root;
}
However, it feels to me that there must be some better way to solve this, since using files located under the project directory is nothing unusual (though it's more common to store configuration and data files under %AppData% or /home). So it doesn't seem right that so many developers would really implement a solution like this to something so common.
What am I missing?
Typically, any constants that your application is dependent on that could change are added to a web.config/app.config file; so that you don't need to recompile the code to change these values. An exception would be a service or library that would require consumers to provide the data via parameters.
When you store paths in a config file, you can use web.config/app.config transforms to change the values based on the build configurations. This allows you to supply different values to your config file settings based on the environment you deploy to.
I posted this question after hours of research. Even after posting it I continued searching for a solution. I saw a lot of threads about this issue, and a lot of solutions that didn't work in my case. Now I stumbled across this, and I used the second approach. Using this solution it works.
It seems so bizarre to me that the access to something so basic would be so non-intuitive. Unfortunately, .NET Core is yet not mature enough.
I'm planning to build my winform into a .exe file. I'm just wondering what to do with the XML files that my application needs?
I did some research and found out that I can add the XML files in the Resource folder before creating a .exe file.
Or I need to create a setup file? When the user runs the setup file, the XML files will be installed into their pc.Now I wonder which one is the best way to go for,
Note: XML files might get modified by the user.
If you want to ship the XML files as seperate to the .EXE then you can set the Copy to Output Directory to Copy if newer. (click on file and then go to properties).
OR if you want it as part of the .EXE I think you can change the Build Action to Embedded Resource.
I personally would create a Setup as per your edit and include the XML files. I usually just add everthing from the bin/release folder that is needed when I create a setup file.
You could either deploy the necessary files along with the executable in the same folder or embed them as resources (if they are read-only). If you need to modify them do not embed them as resources into the executable.
The correct way depends on how you intend to use the files. If the files always are deployed together with your application, the application never writes to them and they are never upgraded without upgrading the application, you can go with them embedded as resources.
If you need to update them separately from the application, you need to have them as physical files.
You don't necessarely need a installation package, unless you need to apply some logic during setup, such as updating the content of the setup based on user input or to check preconditions. The application can just be copied into place regardless of if you have embedded the files or not.
I need some help with paths please!
Basically I have a project with the following folder structure:
Project (root directory which contains the .sln file etc.)
Project/MyProj (contains the code)
Project/MyProjTest (the test folder)
Project/TestResults
Now with this Project I need to have a common folder where I can stick a bunch of files for use with the Application without having to copy the files to multiple locations etc. What is the best way to do this? Ideally I would like to have the folder as Project/ResourcesFolder, so that both the Code folder and Test folder can access it. Now if this is the case how do I call this folder from within C#? I've tried Application.StartupPath, Environment.GetCurrentDirectory but they both just return the CURRENT folder which is not what I want.
Thanks in advance.
You can add a solution folder to your solution and place common files in it.
You'll have to copy the files, you'll want your program to operate the same way after it is deployed. The simplest way to do so is by adding them to your project. In the Properties window, set Build Action = None, Copy to Output Directory = Copy if Newer. The latter setting ensures that you don't waste time copying the files over and over again.
This ensures that the files will be present in the same directory as your EXE. Both when you debug and after you deploy it. Simply use Application.StartupPath to locate them. Creating the Setup project for the app is now very simple as well.
Note that if the files are small you really want to embed them as resources.
.. goes one directory up. That is, from Project/MyProjTest you could access Project/MyProj via ../MyProj.
Use Server.MapPath("~") to get to the root folder of your application. From there you can get to wherever you need.
I have an xml file in a WCF application that describes dependencies. It is loaded when the service facade constructor runs and works great when testing the app alone. The way our separate web testing application is setup is an endpoint in a different (mvc) project - So the relative paths are different to the xml file that we need to load. The question is what would be the best way to load that file from both projects (so that when you run the first project alone it loads the file, but then when that dll is loaded in the second project it can still find the xml file)?
You could copy it to the output directory. You can do this from Visual Studio by right clicking the file, choosing properties and changing "Copy To Output Directory" to "Copy Always".
At runtime you will be able to find the file in the current directory in both projects.
Try Server.MapPath
example:
Server.MapPath (#"~\App_Data\menudata.xml")
then you can place your file in any location relative to the root directory of your website/webservice.
I tried the "Copy To Output" with no luck - for some reason my root path was not where the output path was (which i previously thought)... So to abstract away any headaches from other developers setting up this project I did this:
var _assembly = System.Reflection.Assembly.GetExecutingAssembly();
XDocument xdoc = XDocument.Load(new StreamReader(_assembly.GetManifestResourceStream("TheNamespace.Api.TheFile.xml")));
Which of course requires the file to be an embedded resource.