Unable to load static file once it has been published to Azure, using ASP.NET Core 2.1

Using ASP.NET Core 2.1, I'm trying to load the same static file locally on my dev machine (through Visual Studio 2017) and after the website has been published to the hosting environment (Azure Web Apps).

Consider the directory hierarchy in which the static file (file.xml) to be served resides inside the web root:

wwwroot
    css
    images
    js
    xml
        file.xml

Here's my controller to load the file:

public class DevelopmentController : Controller
{
    private readonly IHostingEnvironment _env;
    public DevelopmentController(IHostingEnvironment env)
    {
        _env = env;
    }

    public async Task<string> Test()
    {
        string result = "";

       // Test Code Here
        XmlDocument doc = new XmlDocument();
        doc.Load(Path.Combine(_env.WebRootPath, "xml", "file.xml"));

        return result;
    }
}

This loads the file locally on my dev machine, however, once the web app is published to Azure, I get the following error:

DirectoryNotFoundException: Could not find a part of the path 'D:\home\site\wwwroot\wwwroot\xml\file.xml'

No matter what I try, I cannot seem to load the file after it has been published to Azure.

NOTE: In ASP.NET MVC 5, I used to be able to use the Server.MapPath() function to load a static file, which worked both locally and in Azure. For example:

doc.Load(System.Web.HttpContext.Current.Server.MapPath("~/xml/file.xml"));

But since upgrading to ASP.NET Core 2.1, I can't figure out the proper way to do this, that will also work when hosted on Azure.

These are the Microsoft Docs, I've used as reference: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-2.1&tabs=aspnetcore2x

UPDATE

In case anyone else experiences the same issue, this is what the problem was:

If you drag and drop a folder into Solution Explorer, the reference does not get automatically added to the .csproj file.

You can check your .csproj file by right clicking on the project and selecting Edit {Project Name}.csproj. For any extra folders you've added to the wwwroot directory, you should see something like:

<ItemGroup>
    <Folder Include="wwwroot\myfolder\" />
</ItemGroup>

If you don't see that, then it won't be published to Azure.

NOTE: If you see <None ..., then that means that the folder has been set to be excluded from publishing.

<ItemGroup>
    <None Include="wwwroot\myexcludedfolder\"
</ItemGroup>

SOLUTION

I just deleted the folder that I had drag and dropped into Solution Explorer, and instead right clicked wwwroot to create the folder that way.

It appears that your issue is that this file is not getting published, and it is not an issue with what happens at runtime.

You would probably see the same behavior if you ran dotnet publish locally, with that file probably missing from the publish folder.

As for why it is not getting published, I'm not an expert of that part, but this answer might help: ASP.NET Core: Exclude or include files on publish

Common errors reference for Azure App Service and IIS with ASP , Obtain troubleshooting advice for common errors when hosting ASP.NET ASP.​NET Core Module stdout Log: The log file is created but empty. This scenario is trapped by the SDK when publishing a BadImageFormatException: Could not load file or assembly public static void Main(string[] args) The ASP.NET Core module V2 running in InProcess mode has to run in its own dedicated Application Pool. According to the documentation you cannot run multiple sites or virtual directories (Web Applications) using the the ASP.NET Core Module in a single Application Pool. Make sure each ASP.NET Core app on IIS gets its own Application Pool.

For those coming across this question but for .js files (or similar), make sure your environment is set correctly in your View.

Default example would be this:

<environment exclude="Development">
    <script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>

Where all work was done into site.js NOT site.min.js. Publishing will use a different environment than what you're developing in and that makes an impact on your results.

Static files in ASP.NET Core, Learn how to serve and secure static files and configure static file hosting middleware View or download sample code (how to download) The default directory is {content root}/wwwroot, but it can be changed via the See Considerations on the security risks when enabling browsing. NET Core 2.1? Static files are stored within the project's web root directory. The default directory is {content root}/wwwroot, but it can be changed via the UseWebRoot method. See Content root and Web root for more information. The app's web host must be made aware of the content root directory. The WebHost.CreateDefaultBuilder method sets the content root

Try:

XmlDocument doc = new XmlDocument();
doc.Load(_env.ContentRootPath + "\\xml\\file.xml", FileMode.Open);

Host and deploy ASP.NET Core, When deploying from Visual Studio, the dotnet publish step occurs A .NET Core app can be published as self-contained deployment or In addition to .exe and .dll files, the publish folder for an ASP.NET Core app typically contains configuration files, static assets, and MVC NET Core web app in Azure. Deploy to Azure. Deploying your ASP.NET Core application to Azure only takes a few steps. You can do it through the Azure web portal, or on the command line using the Azure CLI.

File Providers in ASP.NET Core, NET Core abstracts file system access through the use of File Providers. Static File Middleware uses File Providers to locate static files. Providers and glob patterns to specify which files should be published. When instantiating this provider directly, an absolute directory path is NET Core 2.1 or later. -- Driver version: 2.15.1 -- Using std::atomic implementation for atomic operations -- Checking to see if CXX compiler accepts flag -std=c++11 -- Checking to see if CXX compiler accepts flag -std=c++11 - yes -- Using hash header <functional> and namespace "std" -- Looking for inttypes.h -- Looking for inttypes.h - found -- Looking for stdint.h

Bundle and minify static assets in ASP.NET Core, Once a web page has been requested, the browser caches the static assets (​JavaScript, CSS, This results in improved first page load performance. In ASP.NET Core 2.1 or later, add a new JSON file, named after 88 ms ========​== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========  Similar to Issue #118.. I am running an ASP.NET project in .NET 4.6 using the latest 1.11.3 DocumentDB SDK and whenever I try to do any query using CreateDocumentQuery, the query is created successfully but trying to iterate through the results throws an AggregateException, making DocumentDB useless since queries can't be performed.

ASP.NET Core breaking changes, NET Core and Azure SDKs aren't included in ASP. In ASP.NET Core 2.1 or later projects, replace the old Microsoft. The newer version will be loaded instead of the previous version. header value that the Static File Middleware uses for .csv files has changed to the standards-compliant value text/csv . Uploading files in ASP.net core is largely the same as standard full framework MVC, with the large exception being how you can now stream large files. We will go over both methods of uploading a file in ASP.net core. Model Binding IFormFile (Small Files) When uploading a file via this method, the important thing to […]

Comments
  • Please start with this guidance to determine whether it's a deployment or runtime issue.
  • Hey David, thanks for the suggestion. I didn't know about Kudu. It does appear that the folder in wwwroot is not being published to Azure for some reason. Feel free to add your comment into an answer and I'll mark it as correct. And if you have any suggestion about fixing the folder not being published.
  • Thanks again David. That article, although specific to ASP.NET Core 1.0, was helpful to get me on the right track. I'll update my question with the steps to fix the publish folders for ASP.NET Core 2.1.