21

I have an ASP.Net website that references a class library. In the class library I need to read a file into memory.

At the top level of my class library there is a folder called EmailTemplateHtml containing the file MailTemplate.html that I want to read in.

How can I do this?

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
DreamToCode
  • 271
  • 1
  • 5
  • 11

5 Answers5

46

In Visual Studio, you can configure your library such that the file is copied into the build directory of any project that depends upon it. Then you can get the path to the build directory at runtime in order to read your file.

Step by step instructions, starting from a fresh solution:

  1. Create your application project and your class library project.
  2. Add a reference to the class library project from the application project via Properties->Add->Reference from the application's context menu in Solution Explorer:

    Screenshot showing the *Reference* option Screenshot showing *Reference Explorer*

  3. Create the file in your class library project that you need to read, then set its Copy to Output Directory property to either Copy always or Copy if newer via the Properties pane in Solution Explorer:

    Screenshot showing the *Copy to Output Directory* option

  4. From within either the class library project or your application (either will work with exactly the same code), reference your file relative to Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location). For example:

    using System.Reflection;
    using System.IO;
    
    namespace MyLibrary
    {
        public class MyClass
        {
            public static string ReadFoo()
            {
                var buildDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                var filePath = buildDir + @"\foo.txt";
                return File.ReadAllText(filePath);
            }
        }
    }
    

    (Note that back before .NET Core, you could use a file path relative to System.IO.Directory.GetCurrentDirectory() instead, but this doesn't work in a .NET Core application because the initial working directory for .NET Core apps is the source directory instead of the build directory, apparently because this was needed by ASP.NET Core.)

  5. Go ahead and call your library code from your application code, and everything will work fine. e.g.:

    using Microsoft.AspNetCore.Mvc;
    using MyLibrary;
    
    namespace AspCoreAppWithLib.Controllers
    {
        public class HelloWorldController : Controller
        {
            [HttpGet("/read-file")]
            public string ReadFileFromLibrary()
            {
                return MyClass.ReadFoo();
            }
        }
    }
    
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
  • While I am trying to add reference to text file on disk I am getting the error "make sure that the file is accessible and that it is a valid assembly or com component" – user2934433 Nov 17 '17 at 17:26
  • 2
    @user2934433 You can't add a reference to the text file itself - in step 2, I show adding a reference to the class library *project* that contains the text file. – Mark Amery Nov 17 '17 at 18:04
  • got it! Another doubt here you are referring to the MyLibrary project, is there a way to do just by referring to dll? – user2934433 Nov 17 '17 at 18:36
7
using System.IO;    
using System.Reflection;

public static string ExecutionDirectoryPathName()
    {
         var dirPath = Assembly.GetExecutingAssembly().Location;
         dirPath = Path.GetDirectoryName(dirPath);
         return Path.GetFullPath(Path.Combine(dirPath, "\EmailTemplateHtml\MailTemplate.html"));
    }
vandre
  • 778
  • 6
  • 16
Neeraj Dubey
  • 4,401
  • 8
  • 30
  • 49
  • May need to escape slashes in returned string. Add '@' before string as such: return Path.GetFullPath(Path.Combine(dirPath, @"\EmailTemplateHtml\MailTemplate.html")); – Tyler Nielsen Jun 12 '17 at 20:13
4

If you want to find the path where the assembly is located; from within the assembly then use the following code:

 public static string ExecutionDirectoryPathName
 {
   get
     {
         var dirPath = Assembly.GetExecutingAssembly().Location;
         dirPath = Path.GetDirectoryName(dirPath);
         return dirPath + @"\";
     }
 }
SamCoder
  • 41
  • 3
0

I am not sure what you mean by a folder in the class library but you can use the current working directory if you wish to build a path as follows:

System.IO.Directory.GetCurrentDirectory()

You can then use the Path.Combine() method to build file paths.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Lee
  • 586
  • 3
  • 5
  • Note that before .NET Core, this would return the same as `Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)` (given in other answers here), while in .NET Core it returns the path of the *source* directory instead of the build directory (which is broken for the OP's use case of having a distinct application project and class library project, since when the application is running its working directory *won't* contain files that are from the class library project). – Mark Amery Nov 12 '17 at 22:56
-2

You can add a Static class in your class library with some static methods/properties to set. Set the values from Global.ascx.cs on start app method. Now you can get the values of class library.

Hope this makes clear. Happy coding

  • This is too vague for me to understand the approach you're trying to describe. Some fundamental things - like what the "static methods/properties" you mention are meant to do or contain - are left unstated. – Mark Amery Sep 23 '19 at 21:55