繁体   English   中英

获取要在asp.net Web应用程序中读取的文本文件的完整路径

[英]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静态方法。

  1. 添加对System.Web程序集的引用
  2. using System.Web.Hosting添加
  3. 用单个方法引用网站根目录编写一个类:

     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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM