[英]getting fullpath of text files to be read in asp.net web application
好吧,这已经是一个令人讨厌的问题,在堆栈和Google上进行数十次搜索后,我无法解决。
我有一个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
}
}
我可以在子文件夹中读取文本文件的唯一方法是对路径进行硬编码,如上所示。 正如您在上面看到的那样,我试图以编程方式检索应用程序的基本路径,然后将其添加到files子路径。
正如您在上方看到的那样,在已注释掉的摘录中,我尝试了很多事情。
对于初学者来说,永远不允许Server.MapPath,因为它始终显示为红色,intellisense没有提供任何补救措施,而谷歌搜索对其他任何提供Server.MapPath是IIS方法的帮助也无济于事。 所有其他这些代码片段均不返回任何内容。
我究竟做错了什么? 错误在哪里? 没有标准的方法可以做到,无论您是在开发机上还是在主机虚拟机上,都始终获得正确的基本路径?
根据Darin的建议,代码更新如下:
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检索正确的路径。 为什么类级别的私有变量不检索路径?
您可以声明一个变量,然后在运行时填充该变量以使其只读,然后在属性中使用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;
}
}
在运行时,对this.BasePath的第一个请求将使用MapPath填充私有变量(一次调用),然后对该方法的所有后续调用将使用先前获得的值。
您可以使用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");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.