ASP.NET MVC - Tìm đường dẫn tuyệt đối đến thư mục App_Data từ Trình điều khiển


282

Cách chính xác để tìm đường dẫn tuyệt đối đến thư mục App_Data từ Trình điều khiển trong dự án ASP.NET MVC là gì? Tôi muốn có thể tạm thời làm việc với tệp .xml và tôi không muốn mã hóa đường dẫn.

Điều này không hoạt động:

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        string path = VirtualPathUtility.ToAbsolute("~/App_Data/somedata.xml");

        //.... do whatever 

        return View();
    }

}

Tôi nghĩ bên ngoài bối cảnh web VirtualPathUtility.ToAbsolute () không hoạt động. đường dẫn chuỗi trở lại là "C: \ App_Data \ somedata.xml"

Tôi nên xác định đường dẫn của tệp .xml trong ứng dụng MVC ở đâu? global.asax và dính vào nó một biến cấp ứng dụng?


Tôi đoán theo ý nghĩa của mối quan tâm và khả năng kiểm tra - VirtualPathUtility.ToAbsolute () không nên hoạt động. Nhưng sau đó, cách đúng đắn để làm điều này là gì?
BuddyJoe

Câu trả lời:


398

ASP.NET MVC1 -> MVC3

string path = HttpContext.Current.Server.MapPath("~/App_Data/somedata.xml");

ASP.NET MVC4

string path = Server.MapPath("~/App_Data/somedata.xml");


Tham khảo MSDN:

Phương thức httpServerUtility.MapPath


6
@Cleiton Ngoại trừ Url.Content cung cấp URL, không phải đường dẫn máy chủ.
Andrew Dunkman

8
đối với mvc4, nó chỉ là Server.MapPath ()
SeriousM

6
Cách MVC4 không hoạt động, tôi phải sử dụng Currenthoặc Server.MapPath(...)như SeriousM đã đề cập.
gligoran

26
Sử dụngSystem.Web.Hosting.HostingEnvironment.MapPath()
Vince Panuccio

1
Các cuộc gọi đến HTTPContext. Hiện tại không hoạt động trong một số trường hợp không có HTTPContext (application_start, v.v.)
mcintyre321

274
string path = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();

Đây có lẽ là một cách "chính xác" hơn để có được nó.


25
Bởi vì nó không mã hóa chuỗi "App_Data". Điều đó có thể thay đổi trong các phiên bản trong tương lai hoặc khác biệt trong Mono, v.v.
Alex

19
Điều thú vị về câu trả lời này là tôi có thể sử dụng nó trong dự án Mô hình của mình mà không cần tham khảo system.web, do đó giúp giữ một sự tách biệt rõ ràng. Đẹp quá
Frans

10
Bài đăng trên blog Pete đề cập đến cũng nói về lý do tại sao sử dụng điều này có thể không phải là một ý tưởng tuyệt vời.
Andy

13
Không được ghi lại trong MSDN , do đó không nên được sử dụng.
Alexander Abramov

10
Mã hóa cứng một chuỗi khác thay vì "App_Data" không phải là cách "chính xác". Ngoài ra, không có nhiều miền ứng dụng trong .NET Core.
UserControl

139

Tôi cố gắng tập thói quen sử dụng HostingEnvironmentthay vì Servernó hoạt động trong bối cảnh dịch vụ WCF.

 HostingEnvironment.MapPath(@"~/App_Data/PriceModels.xml");

6
Server.MapPath () cuối cùng gọi HostingEn Môi trường.MapPath (), xem stackoverflow.com/questions/944219/
Todd

3
Đây là mục yêu thích của tôi vì tôi có thể sử dụng nó bên ngoài bộ điều khiển của mình. Đây là trong System.Web.Hostingkhông gian tên trong trường hợp bất cứ ai cần biết có liên quan using. Tham chiếu: docs.microsoft.com/en-us/dotnet/api/ từ
MDMower

7

Cách chính xác nhất là sử dụng HttpContext.Current.Server.MapPath("~/App_Data");. Điều này có nghĩa là bạn chỉ có thể truy xuất đường dẫn từ một phương thức HttpContextcó sẵn. Điều này có ý nghĩa: thư mục App_Data là cấu trúc thư mục dự án web [1].

Nếu bạn cần đường dẫn đến ~ / App_Data từ một lớp nơi bạn không có quyền truy cập vào, HttpContextbạn luôn có thể tiêm giao diện nhà cung cấp bằng cách sử dụng bộ chứa IoC của mình:

public interface IAppDataPathProvider
{
    string GetAppDataPath();
}

Triển khai nó bằng cách sử dụng HttpApplication:

public class AppDataPathProvider : IAppDataPathProvider
{
    public string GetAppDataPath()
    {
        return MyHttpApplication.GetAppDataPath();
    }
}

Nơi MyHttpApplication.GetAppDataPathtrông như:

public class MyHttpApplication : HttpApplication
{
    // of course you can fetch&store the value at Application_Start
    public static string GetAppDataPath()
    {
        return HttpContext.Current.Server.MapPath("~/App_Data");
    }
}

[1] http://msdn.microsoft.com/en-us/l Library / ex526337% 28v = vs.100% 29.aspx


Làm thế nào có thể tĩnh HttpContext.Currentbao giờ không có sẵn ở một nơi nếu bạn đang sử dụng nó - qua một container IoC - ở một nơi khác? Trường hợp tài sản tĩnh sẽ không có sẵn?
M. Mimpen 10/03/2015

Nó sẽ chỉ có sẵn trong dự án web. Điều này có trả lời câu hỏi của bạn không? Tôi không chắc là tôi hiểu đầy đủ. Hôm nay tôi nghĩ rằng tôi có thể đã giải quyết vấn đề (đơn giản thừa nhận) này một chút khác biệt. Tôi có thể đã sử dụng cùng một giao diện nhà cung cấp nhưng thiết lập nó trong Application_Start với đường dẫn gốc của ứng dụng.
Daniel Lidström

Không, HttpContext.C hiện không chỉ có sẵn trong dự án web ... Nếu bạn tham chiếu một dự án có GetAppDataPath (), thì nó cũng sẽ luôn cần phải tham khảo httpContext.C hiện tại. Tức là nếu bạn sử dụng thư viện A sử dụng thư viện B, ứng dụng của bạn sẽ cần tham chiếu đến thư viện A B.
M. Mimpen 11/03/2015

Đôi khi thật thuận tiện khi không truy cập trực tiếp vào HTTPCext, thay vào đó là trải qua một mức độ gián tiếp. Hãy nghĩ thử nghiệm đơn vị chẳng hạn. Khả năng kiểm tra thường là lý do tại sao tôi làm mọi thứ theo cách này. Nhưng tôi nghĩ rằng bạn không chính xác về tuyên bố của bạn. Chỉ giao diện cần được chia sẻ giữa các hội đồng. Đó là lý do bạn có thể giả định nó để kiểm tra, tức là bạn không cần httpContext.C hiện tại cho các bài kiểm tra. Xin lỗi nếu tôi gây nhầm lẫn cho bạn ...
Daniel Lidström

6

Phil Haak có một ví dụ mà tôi nghĩ là ổn định hơn một chút khi xử lý các đường dẫn với các dấu tách thư mục kiểu "\" điên rồ. Nó cũng an toàn xử lý nối đường dẫn. Nó được cung cấp miễn phí trong System.IO

var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);

Tuy nhiên, bạn cũng có thể thử "AppDomain.CienDomain.BaseDirector" thay vì "Server.MapPath".


4
string filePath = HttpContext.Current.Server.MapPath("~/folderName/filename.extension");

HOẶC LÀ

string filePath = HttpContext.Server.MapPath("~/folderName/filename.extension");

1
Mặc dù mã này có thể giúp giải quyết vấn đề, việc cung cấp bối cảnh bổ sung về lý do và / hoặc cách nó trả lời câu hỏi sẽ cải thiện đáng kể giá trị lâu dài của nó. Vui lòng chỉnh sửa câu trả lời của bạn để thêm một số lời giải thích.
oɔɯǝɹ

1
string Index = i;
            string FileName = "Mutton" + Index + ".xml";
            XmlDocument xmlDoc = new XmlDocument();

            var path = Path.Combine(Server.MapPath("~/Content/FilesXML"), FileName);
            xmlDoc.Load(path); // Can use xmlDoc.LoadXml(YourString);

đây là giải pháp tốt nhất để có được con đường chính xác là cần thiết cho bây giờ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.