Reputation: 4882
I have a solution which has two presentation layers. One is using ASP.NET MVC, the other WinForms. Both projects depend on a third projecs which does some business logic and is a class library. The third project has the following method which works fine in WinForms, but doesnt work in MVC:
public static string[] Dictionary()
{
if (_dictionary == null)
{
if (File.Exists("dict.txt"))
_dictionary = File.ReadAllLines("dict.txt");
}
return _dictionary;
}
So when I am using the WinForms GUI the file is found, but when I am using the MVC website, the project can't find it.
When building the solution dict.txt is placed in bin/debug of the WinForms project.
It is placed in /bin in the MVC project.
Where should I place the file in the MVC proejct?
Upvotes: 0
Views: 326
Reputation: 675
So when I am using the WinForms GUI the file is found, but when I am using the MVC website, the project can't find it.
To answer the reason why you are observing the difference is called the current working directory. By default, when VS.NET launches Windows apps or consoles, the working directory is to the relevant bin directory.
All relative file operations, such as File.ReadAllLines("the.file")
, will concatenate to an absolute file path as per below.
Path.Combine(Directory.GetCurrentDirectory(), "the.file");
ASP.NET's working directory would not correlate to the root of your web application.
Where should I place the file in the MVC proejct?
As suggested by @dariogriffo, it should be placed in the ~/App_Data/*
directory.
I have a solution which has two presentation layers. One is using ASP.NET MVC, the other WinForms. Both projects depend on a third projecs which does some business logic and is a class library.
So now you are in a little bit of a pickle over here with your current implementation and the way the current working directory is implemented. Without delving into too much detail, I suggest that the code figures out how to load the file indirectly such as passing in an interface with a contract such as the following.
public interface IDictionaryRepository {
IEnumerable<string> LoadAllWords();
}
With the above, you can change your business logic to the following
public static string[] Dictionary()
{
if (_dictionary == null)
{
_dictionary = _dictionaryRepository.LoadAllWords().ToArray();
}
return _dictionary;
}
The benefit of the above abstraction is that you may then easily substitute the file finding logic as per the other suggestions easily, and maybe migrate your dictionary to be hosted in a database somewhere.
Upvotes: 1
Reputation: 455
server applications can have 2 paths - virtual and logical. You can reference to one or another using MapPath() method.
I thinki you need to provide full path to this file in MVC, check this out:
Server.MapPath("~\\bin\\dict.txt")
Upvotes: 0
Reputation: 4274
You can place them in the App_Data Forlder, and then reference them like this
var fileName = Path.Combine(System.Web.HttpContext.Current.Server.MapPath(@"~/App_Data"),"dict.txt");
Upvotes: 2