如何在托管的 ASP.NET Web API 中使用 System.IO.File 提供相对路径?
Posted
技术标签:
【中文标题】如何在托管的 ASP.NET Web API 中使用 System.IO.File 提供相对路径?【英文标题】:How to provide a relative path using System.IO.File inside a hosted ASP.NET Web API? 【发布时间】:2021-11-29 11:23:02 【问题描述】:我有一个作为应用服务托管在 Azure 上的 ASP.NET Web API。我有每月自动调用一次端点的工作流。但是,由于以下错误,这些触发器一直失败:
"body": "Could not find a part of the path 'C:\\home\\site\\The-Food-Works-WebAPI\\Assets\\loyalty-template.html'."
在这个端点,我试图通过以下代码访问一个文件(也在这个 web api 项目中):
string body = System.IO.File.ReadAllText("..\\The-Food-Works-WebAPI\\Assets\\loyalty-template.html");
如果我必须在本地运行端点,一切都会按预期工作。我相信相对路径没问题,但是由于访问它的方式(通过 System.IO.File),它希望文件保存在本地?
编辑:(使用嵌入式资源):
var resourceName = "..//The-Food-Works-WebAPI//Assets//loyalty-template.html";
string body;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
TextReader tr = new StreamReader(stream);
body = tr.ReadToEnd();
Azure 现在给出以下错误:
"body": "Value cannot be null. (Parameter 'stream')"
【问题讨论】:
作为替代方案,您是否考虑过使用嵌入式资源? (Assembly.GetManifestResourceStream
?) 这样您就可以始终确保内容存在,因为它会嵌入到您的程序集中。
Azure 应用服务使用 D:\home\site\etc
而不是 C:\home\site
顺便说一句。我想你猜错了驱动器号。
您的resourceName
错误。您需要手动编辑您的.csproj
为资源设置<LogicalName>
,然后将that 用于resourceName
(您应该将其存储为const
)。见这里:***.com/questions/3605514/name-of-embedded-resource/…
另外,您需要处理您的 StreamReader
实例。始终使用 using
块。
我强烈建议始终设置显式<LogicalName>
,否则MSBuild会根据文件相对于.csproj
的路径生成资源名称,这意味着它如果您在文件系统中移动文件,将会发生变化(完全出乎意料!)。我对微软选择隐藏<LogicalName>
而不是在“属性”窗口中公开它感到惊讶和失望。 (替代方法是使用.resx
/.resources
文件,但它们有点过时并且没有增加任何价值 - 我认为它更多的是对 VB.NET 用户的帮助,而不是我们今天应该使用的东西)
【参考方案1】:
谢谢@Dai,我将上述 cmets 转换为答案,以便帮助其他社区成员:
所以在更改您的资源名称并编辑您的
.csproj
为资源设置<LogicalName>
,然后将 that 用于resourceName
以及在处理StreamReader
实例之后并通过使用using
块有望解决问题。
并且建议始终设置显式的<LogicalName>
,否则MSBuild 会根据文件相对于.csproj
的路径生成资源名称,这意味着如果您使用它,它会发生变化(完全出乎意料!)永远在你的文件系统中移动文件。
【讨论】:
以上是关于如何在托管的 ASP.NET Web API 中使用 System.IO.File 提供相对路径?的主要内容,如果未能解决你的问题,请参考以下文章
如何在托管的 ASP.NET Web API 中使用 System.IO.File 提供相对路径?
请求实体对于自托管 ASP.Net Web API 来说太大
asp.net web api 自托管 / owin / katana