获取要在 Web 应用程序中读取的文本文件的完整路径 asp.net
本文关键字:文件 路径 net asp 文本 获取 Web 应用程序 读取 | 更新日期: 2023-09-27 18:37:12
嗯,这是一个非常烦人的问题,在堆栈和谷歌上搜索了几十次后,我无法解决。
我有一个 Asp.Net Web 应用程序,解决方案本身有 7 个项目,其中一个是 MVC 项目,其中驻留着如下所示的类。
using System;
using System.Web.Hosting;
namespace MyApp.Notifications
{
public class CustomEmails
{
private readonly string basePath = "C:''Users''MyUser''MyAppName''";
//HostingEnvironment.MapPath("~''MyAppName")
//Server.MapPath("~")
//HostingEnvironment.ApplicationPhysicalPath("~");
//HostingEnvironment.ApplicationVirtualPath;
var subject = File.ReadAllText(basePath + "Notifications''EmailTemplates''EmailConfirmationEvent_Subject.txt");
//rest of classes code here
}
}
读取子文件夹中的文本文件的唯一方法是对路径进行硬编码,如上所示。正如您在上面看到的,我正在尝试以编程方式检索应用程序的基本路径,然后将其附加到文件子路径。
正如你在上面看到的,在注释掉的片段中,我尝试了很多东西。
对于初学者来说,Server.MapPath永远不会被允许,因为它总是红色的,智能感知不提供任何补救措施,谷歌搜索对提供Server.MapPath是一种IIS方法没有多大帮助。所有其他代码片段都不返回任何内容。
我做错了什么?错误在哪里?难道没有一种标准方法可以做到这一点,因此无论是在开发计算机上还是在主机虚拟机上,您始终可以获得正确的基本路径?
根据达林的建议,代码更新如下;
public class EmailEvents
{
private static readonly string basePath = CustomEmails.GetWebsiteRoot();
public class EmailAddressVerified : IEventHandler<EmailVerifiedEvent<UserAccount>>
{
public void Handle(EmailVerifiedEvent<UserAccount> evt)
{
dynamic smtp = new SmtpMessageDelivery();
var localAppPath = CustomEmails.GetWebsiteRoot();
var htmlBody = CustomEmails.GetHtmlEmailMessage(DomainClasses.Enums.EmailType.AccountConfirmation);
//{ProductionChange} --change the first parameter to false in production
htmlBody = CustomEmails.FillEmailPlaceholderText(false, htmlBody, evt.Account);
htmlBody = htmlBody.Replace(CustomEmails.EmailTextPlaceholders.HtmlFileKey, EncryptDecrypt.EncryptQueryString(Guid.NewGuid().ToString()));
var subject = File.ReadAllText(Path.Combine(basePath, "Notifications", "EmailTemplates", "EmailConfirmationEvent_Subject.txt"));
subject = subject.Replace(CustomEmails.EmailTextPlaceholders.ApplicationName, CustomEmails.EmailPlaceholderValues.ApplicationName);
var msg = new Message { To = evt.Account.Email, Subject = subject, Body = htmlBody };
smtp.Send(msg);
}
}
}
在上面的示例中,basePath 始终不是,但 localAppPath 检索正确的路径。为什么类级私有变量不检索路径?
HostingEnvironment.MapPath
静态方法。
- 添加对
System.Web
程序集的引用 - 添加
using System.Web.Hosting
使用引用网站根目录的单个方法编写一个类:
using System.Web.Hosting; namespace MyApp.Notifications { public class CustomEmails { public static string GetWebsiteRoot() { // Get the website root return HostingEnvironment.MapPath("~/"); } } }
备注:HostingEnvironment.MapPath
只能在 ASP.NET 虚拟主机中工作。如果您尝试在外部(例如单元测试或桌面应用程序)使用它,它将不会返回所需的结果。
在这种情况下,最好让您的函数将网站根路径作为依赖项。这将使它们更容易进行单元测试。只有在组合根中,您才会使用正确的方法来注入路径。对于 ASP.NET Web 上下文,这将是HostingEnvironment.MapPath
方法。
此外,当您处理目录路径时,您完全希望使用 Path.Combine
方法而不是您在问题中使用的+
运算符。例如:
string root = CustomEmails.GetWebsiteRoot();
string path = Path.Combine(root, "Notifications", "EmailTemplates", "EmailConfirmationEvent_Subject.txt");
您可以声明一个变量,然后稍后在运行时仅使用 get 填充该变量以使其只读,然后在属性中使用 Server.MapPath。你不能在编译时像在类声明中那样这样做,因为它无法确定字符串 const 是什么,因为 Server.MapPath 无法解析为它可以使用的 const,因为它几乎肯定会随着部署而改变。
public class CustomEmails
{
private string _basePath = null;
private string BasePath
{
get
{
if ( _basePath == null )
{
this._basePath = Server.MapPath('...');
}
return _basePath;
}
}
在运行时,您对此的第一个请求。BasePath 将使用 MapPath(一次性调用)填充私有变量,然后对该方法的所有后续调用都将使用先前获得的值。