ASP.NET MVC - 从控制器中查找 App_Data 文件夹的绝对路径

Posted

技术标签:

【中文标题】ASP.NET MVC - 从控制器中查找 App_Data 文件夹的绝对路径【英文标题】:ASP.NET MVC - Find Absolute Path to the App_Data folder from Controller 【发布时间】:2010-11-19 02:49:32 【问题描述】:

从 ASP.NET MVC 项目的控制器中找到 App_Data 文件夹的绝对路径的正确方法是什么?我希望能够临时使用 .xml 文件,并且我不想硬编码路径。

这不起作用:

[HandleError]
public class HomeController : Controller

    public ActionResult Index()
    
        string path = VirtualPathUtility.ToAbsolute("~/App_Data/somedata.xml");

        //.... do whatever 

        return View();
    


我认为在网络环境之外 VirtualPathUtility.ToAbsolute() 不起作用。 字符串路径返回为“C:\App_Data\somedata.xml”

我应该在哪里确定 .xml 文件在 MVC 应用程序中的路径? global.asax 并将其粘贴为应用程序级变量?

【问题讨论】:

我猜在关注点和可测试性的分离意义上 - VirtualPathUtility.ToAbsolute() 不应该工作。但是,这样做的正确方法是什么? 【参考方案1】:

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");


MSDN 参考:

HttpServerUtility.MapPath Method

【讨论】:

@Cleiton 除了 Url.Content 提供的是 URL,而不是服务器路径。 对于 mvc4 它只有 Server.MapPath() MVC4 方式不起作用,我不得不使用CurrentServer.MapPath(...),正如 SeriousM 提到的那样。 使用System.Web.Hosting.HostingEnvironment.MapPath() 对 HttpContext.Current 的调用在某些没有 HttpContext(application_start 等)的情况下不起作用【参考方案2】:
string path = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();

这可能是一种更“正确”的获取方式。

【讨论】:

因为它没有硬编码“App_Data”字符串。这可能会在未来的版本中发生变化,或者在 Mono 等中有所不同。 这个答案的好处是我可以在我的模型项目中使用它而不引用system.web,从而有助于保持干净的分离。不错! Pete 引用的博文还谈到了为什么使用它可能不是一个好主意。 MSDN 中未记录,因此不应使用。 硬编码另一个字符串而不是“App_Data”不是“正确”的方式。此外,.NET Core 中没有更多的应用程序域。【参考方案3】:

我尝试养成使用 HostingEnvironment 而不是 Server 的习惯,因为它也适用于 WCF 服务的上下文。

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

【讨论】:

Server.MapPath() 最终调用 HostingEnvironment.MapPath(),见***.com/questions/944219/… 这是我的最爱,因为我可以在控制器之外使用它。这是在System.Web.Hosting 命名空间中,以防有人需要知道相关的using。参考:docs.microsoft.com/en-us/dotnet/api/…【参考方案4】:

最正确的方法是使用HttpContext.Current.Server.MapPath("~/App_Data");。这意味着您只能从HttpContext 可用的方法中检索路径。有道理:App_Data 目录是一个 Web 项目文件夹结构 [1]。

如果您需要从无权访问 HttpContext 的类到 ~/App_Data 的路径,您始终可以使用您的 IoC 容器注入提供程序接口:

public interface IAppDataPathProvider

    string GetAppDataPath();

使用您的HttpApplication 实现它:

public class AppDataPathProvider : IAppDataPathProvider

    public string GetAppDataPath()
    
        return MyHttpApplication.GetAppDataPath();
    

MyHttpApplication.GetAppDataPath 的样子:

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/library/ex526337%28v=vs.100%29.aspx

【讨论】:

静态HttpContext.Current 怎么可能 如果您在另一个地方使用它 - 通过 IoC 容器 - 在另一个地方?静态属性在哪里不可用? 它只在 web 项目中可用。这回答了你的问题了吗?我不确定我是否完全理解。今天我想我可能已经解决了这个(诚然简单的)问题有点不同。我可能会使用相同的提供程序接口,但在 Application_Start 中使用应用程序根路径进行设置。 不,HttpContext.Current 不仅在 Web 项目中可用...如果您引用具有 GetAppDataPath() 的项目,它也总是需要引用 HttpContext.Current。 IE。如果您使用使用库 B 的库 A,您的应用程序将需要对库 A B的引用。 有时不直接访问 HttpContext 会很方便,而是通过一个间接级别。以单元测试为例。可测试性通常是我以这种方式做事的原因。但我认为你的说法是不正确的。只有接口需要在程序集之间共享。这就是您可以模拟它进行测试的原因,即您不需要 HttpContext.Current 进行测试。对不起,如果我让你感到困惑......【参考方案5】:

Phil Haak 有一个示例,我认为它在处理带有疯狂“\”样式目录分隔符的路径时更加稳定。它还可以安全地处理路径连接。它在 System.IO 中免费提供

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

但是,您也可以尝试“AppDomain.CurrentDomain.BaseDirector”而不是“Server.MapPath”。

【讨论】:

【参考方案6】:
string filePath = HttpContext.Current.Server.MapPath("~/folderName/filename.extension");

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

【讨论】:

虽然此代码可能有助于解决问题,但提供有关它为什么和/或如何回答问题的额外上下文将显着提高其长期价值。请编辑您的答案以添加一些解释。【参考方案7】:
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);

这是获得现在真正需要的路径的最佳解决方案

【讨论】:

【参考方案8】:

这样我就得到了托管路径。

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;

namespace IHostingEnvironmentExample.Controllers

    public class HomeController : Controller
    
        private IHostingEnvironment _env;
        public HomeController(IHostingEnvironment env)
        
            _env = env;
        
        public IActionResult Index()
        
            var webRoot = _env.WebRootPath;
            var file = System.IO.Path.Combine(webRoot, "test.txt");
            System.IO.File.WriteAllText(file, "Hello World!");
            return View();
        
    

https://forums.asp.net/t/1696005.aspx?How+to+get+Local+Server+path+in+mvc

【讨论】:

以上是关于ASP.NET MVC - 从控制器中查找 App_Data 文件夹的绝对路径的主要内容,如果未能解决你的问题,请参考以下文章

如何查找从 ASP.NET MVC 页面单击的表格单元格值?

将Asp.Net WebAPI从AngularJS App的Asp.Net MVC站点移动到一个单独的站点

ASP.NET Web API 从 MVC 4 控制器失败

如何从 ASP.NET MVC 控制器的局部视图中读取值

ASP.NET MVC Web App 从 MySQL 数据库中获取不完整的数据

ASP.NET MVC 控制器不会从 LINQ lambda 捕获异常