获取要在 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 检索正确的路径。为什么类级私有变量不检索路径?

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

您可以使用

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");

您可以声明一个变量,然后稍后在运行时仅使用 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(一次性调用)填充私有变量,然后对该方法的所有后续调用都将使用先前获得的值。