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 方式不起作用,我不得不使用Current
或Server.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站点移动到一个单独的站点