15 KiB
title | author | description | ms.author | ms.custom | ms.date | uid |
---|---|---|---|---|---|---|
File Providers in ASP.NET Core | guardrex | Learn how ASP.NET Core abstracts file system access through the use of File Providers. | riande | mvc | 08/01/2018 | fundamentals/file-providers |
File Providers in ASP.NET Core
By Steve Smith and Luke Latham
ASP.NET Core abstracts file system access through the use of File Providers. File Providers are used throughout the ASP.NET Core framework:
- IHostingEnvironment exposes the app's content root and web root as
IFileProvider
types. - Static File Middleware uses File Providers to locate static files.
- Razor uses File Providers to locate pages and views.
- .NET Core tooling uses File Providers and glob patterns to specify which files should be published.
View or download sample code (how to download)
File Provider interfaces
The primary interface is IFileProvider. IFileProvider
exposes methods to:
- Obtain file information (IFileInfo).
- Obtain directory information (IDirectoryContents).
- Set up change notifications (using an IChangeToken).
IFileInfo
provides methods and properties for working with files:
- Exists
- IsDirectory
- Name
- Length (in bytes)
- LastModified date
You can read from the file using the IFileInfo.CreateReadStream method.
The sample app demonstrates how to configure a File Provider in Startup.ConfigureServices
for use throughout the app via dependency injection.
File Provider implementations
Three implementations of IFileProvider
are available.
::: moniker range=">= aspnetcore-2.0"
Implementation | Description |
---|---|
PhysicalFileProvider | The physical provider is used to access the system's physical files. |
ManifestEmbeddedFileProvider | The manifest embedded provider is used to access files embedded in assemblies. |
CompositeFileProvider | The composite provider is used to provide combined access to files and directories from one or more other providers. |
::: moniker-end
::: moniker range="< aspnetcore-2.0"
Implementation | Description |
---|---|
PhysicalFileProvider | The physical provider is used to access the system's physical files. |
EmbeddedFileProvider | The embedded provider is used to access files embedded in assemblies. |
CompositeFileProvider | The composite provider is used to provide combined access to files and directories from one or more other providers. |
::: moniker-end
PhysicalFileProvider
The PhysicalFileProvider provides access to the physical file system. PhysicalFileProvider
uses the System.IO.File type (for the physical provider) and scopes all paths to a directory and its children. This scoping prevents access to the file system outside of the specified directory and its children. When instantiating this provider, a directory path is required and serves as the base path for all requests made using the provider. You can instantiate a PhysicalFileProvider
provider directly, or you can request an IFileProvider
in a constructor through dependency injection.
Static types
The following code shows how to create a PhysicalFileProvider
and use it to obtain directory contents and file information:
var provider = new PhysicalFileProvider(applicationRoot);
var contents = provider.GetDirectoryContents(string.Empty);
var fileInfo = provider.GetFileInfo("wwwroot/js/site.js");
Types in the preceding example:
provider
is anIFileProvider
.contents
is anIDirectoryContents
.fileInfo
is anIFileInfo
.
The File Provider can be used to iterate through the directory specified by applicationRoot
or call GetFileInfo
to obtain a file's information. The File Provider has no access outside of the applicationRoot
directory.
The sample app creates the provider in the app's Startup.ConfigureServices
class using IHostingEnvironment.ContentRootFileProvider:
var physicalProvider = _env.ContentRootFileProvider;
Obtain File Provider types with dependency injection
Inject the provider into any class constructor and assign it to a local field. Use the field throughout the class's methods to access files.
::: moniker range=">= aspnetcore-2.0"
In the sample app, the IndexModel
class receives an IFileProvider
instance to obtain directory contents for the app's base path.
Pages/Index.cshtml.cs:
The IDirectoryContents
are iterated in the page.
Pages/Index.cshtml:
::: moniker-end
::: moniker range="< aspnetcore-2.0"
In the sample app, the HomeController
class receives an IFileProvider
instance to obtain directory contents for the app's base path.
Controllers/HomeController.cs:
The IDirectoryContents
are iterated in the view.
Views/Home/Index.cshtml:
::: moniker-end
::: moniker range=">= aspnetcore-2.0"
ManifestEmbeddedFileProvider
The ManifestEmbeddedFileProvider is used to access files embedded within assemblies. The ManifestEmbeddedFileProvider
uses a manifest compiled into the assembly to reconstruct the original paths of the embedded files.
[!NOTE] The
ManifestEmbeddedFileProvider
is available in ASP.NET Core 2.1 or later. To access files embedded in assemblies in ASP.NET Core 2.0 or earlier, see the ASP.NET Core 1.x version of this topic.
To generate a manifest of the embedded files, set the <GenerateEmbeddedFilesManifest>
property to true
. Specify the files to embed with <EmbeddedResource>:
Use glob patterns to specify one or more files to embed into the assembly.
The sample app creates an ManifestEmbeddedFileProvider
and passes the currently executing assembly to its constructor.
Startup.cs:
var manifestEmbeddedProvider =
new ManifestEmbeddedFileProvider(Assembly.GetEntryAssembly());
Additional overloads allow you to:
- Specify a relative file path.
- Scope files to a last modified date.
- Name the embedded resource containing the embedded file manifest.
Overload | Description |
---|---|
ManifestEmbeddedFileProvider(Assembly, String) | Accepts an optional root relative path parameter. Specify the root to scope calls to GetDirectoryContents to those resources under the provided path. |
ManifestEmbeddedFileProvider(Assembly, String, DateTimeOffset) | Accepts an optional root relative path parameter and a lastModified date (DateTimeOffset) parameter. The lastModified date scopes the last modification date for the IFileInfo instances returned by the IFileProvider. |
ManifestEmbeddedFileProvider(Assembly, String, String, DateTimeOffset) | Accepts an optional root relative path, lastModified date, and manifestName parameters. The manifestName represents the name of the embedded resource containing the manifest. |
::: moniker-end
::: moniker range="< aspnetcore-2.0"
EmbeddedFileProvider
The EmbeddedFileProvider is used to access files embedded within assemblies. Specify the files to embed with the <EmbeddedResource> property in the project file:
<ItemGroup>
<EmbeddedResource Include="Resource.txt" />
</ItemGroup>
Use glob patterns to specify one or more files to embed into the assembly.
The sample app creates an EmbeddedFileProvider
and passes the currently executing assembly to its constructor.
Startup.cs:
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
Embedded resources don't expose directories. Rather, the path to the resource (via its namespace) is embedded in its filename using .
separators. In the sample app, the baseNamespace
is FileProviderSample.
.
The EmbeddedFileProvider(Assembly, String) constructor accepts an optional baseNamespace
parameter. Specify the base namespace to scope calls to GetDirectoryContents to those resources under the provided namespace.
::: moniker-end
CompositeFileProvider
The CompositeFileProvider combines IFileProvider
instances, exposing a single interface for working with files from multiple providers. When creating the CompositeFileProvider
, pass one or more IFileProvider
instances to its constructor.
::: moniker range=">= aspnetcore-2.0"
In the sample app, a PhysicalFileProvider
and a ManifestEmbeddedFileProvider
provide files to a CompositeFileProvider
registered in the app's service container:
::: moniker-end
::: moniker range="< aspnetcore-2.0"
In the sample app, a PhysicalFileProvider
and an EmbeddedFileProvider
provide files to a CompositeFileProvider
registered in the app's service container:
::: moniker-end
Watch for changes
The IFileProvider.Watch method provides a scenario to watch one or more files or directories for changes. Watch
accepts a path string, which can use glob patterns to specify multiple files. Watch
returns an IChangeToken. The change token exposes:
- HasChanged: A property that can be inspected to determine if a change has occurred.
- RegisterChangeCallback: Called when changes are detected to the specified path string. Each change token only calls its associated callback in response to a single change. To enable constant monitoring, use a TaskCompletionSource (shown below) or recreate
IChangeToken
instances in response to changes.
In the sample app, the WatchConsole console app is configured to display a message whenever a text file is modified:
::: moniker range=">= aspnetcore-2.0"
::: moniker-end
::: moniker range="< aspnetcore-2.0"
::: moniker-end
Some file systems, such as Docker containers and network shares, may not reliably send change notifications. Set the DOTNET_USE_POLLING_FILE_WATCHER
environment variable to 1
or true
to poll the file system for changes every four seconds (not configurable).
Glob patterns
File system paths use wildcard patterns called glob (or globbing) patterns. Specify groups of files with these patterns. The two wildcard characters are *
and **
:
*
Matches anything at the current folder level, any filename, or any file extension. Matches are terminated by /
and .
characters in the file path.
**
Matches anything across multiple directory levels. Can be used to recursively match many files within a directory hierarchy.
Glob pattern examples
directory/file.txt
Matches a specific file in a specific directory.
directory/*.txt
Matches all files with .txt extension in a specific directory.
directory/*/appsettings.json
Matches all appsettings.json
files in directories exactly one level below the directory folder.
directory/**/*.txt
Matches all files with .txt extension found anywhere under the directory folder.