15

Problem

When I try to add a migration to my code, e.g: dnx ef migrations add initial,

the env.WebRootPath in Startup(IHostingEnvironment env) is null.

This will give me compilation errors when adding a new migration or updating the database.

The Code

In the Startup.cs class I have these lines in the constructor:

public Startup(IHostingEnvironment env)
{
    // ...
    MyStaticClass.Initialize(env.WebRootPath);
    // ...
    _hostingEnvironment = env;
}

Here env.WebRootPath is null and in the Initialize function this throws an exception.

In the ConfigureServices function of the Startup.cs I resolve my class dependencies:

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddInstance<IMyService>(new MyService(_hostingEnvironment.WebRootPath))
    // Note: _hostingEnvironment is set in the Startup constructor.
    // ...
}

Notes

  • I can build, run, and deploy the code fine. Everything works!

  • However I made a change in the model and want to add a migration with this command: dnx ef migrations add MyMigration then I see the compilation errors in the package manager console.

  • I am using ASP 5 web application, and Entity Framework 7

A-Sharabiani
  • 13,270
  • 12
  • 87
  • 109

7 Answers7

46

The env.WebRootPath can also be null if the wwwroot folder has been inadvertantly removed from the root of your project. Adding a wwwroot folder to the root of your project will also fix this issue.

Ricky Keane
  • 1,220
  • 2
  • 12
  • 18
17

There is an issue reported on github regarding my problem:

https://github.com/aspnet/EntityFramework/issues/4494

I used the workaround in the comments now it seems to be working fine:

if (string.IsNullOrWhiteSpace(_env.WebRootPath))
{
   env.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
}
A-Sharabiani
  • 13,270
  • 12
  • 87
  • 109
8

This thread is I believe best one to find out the answer for this problem.

Method 1:

I spent a bit of time looking for answer and I figured out that the way to sort this out rather than check if path exists(in controller or methods) is to update your Program.cs:

    public static async Task Main(string[] args)
    {
        IWebHost webHost = CreateWebHostBuilder(args).Build();

        await webHost.RunAsync();
    }

    private static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseWebRoot("wwwroot")
            .UseStartup<Startup>();

This way you will ensure that there will be webroot folder ready for placing files inside it and _environment.webRootPath will not be null and also you can even customize the name of the folder.

Method 2

The second option to do this is to manually add "wwwroot" folder in the project from Visual Studio level. The program should pick this up and allocate as wwwroot folder:

Method no 2

4

In my case, the problem was that the wwwroot folder was empty and VS didn't recognized it.

The solution: create a placeholder.txt in wwwroot.

Hope it helps.

0

In case someone still faces this problem, in my case the issue was default constructor which I created it for a test.

So, remove the default constructor if any.

Ajay2707
  • 5,345
  • 6
  • 34
  • 52
M.Nour Berro
  • 477
  • 4
  • 14
0

I got the error while file uploading in asp.net core application with Telerik controls. The error is not related to Telerik control.

While investigation I got the description that This is the variable which gives the same functionality as Server.MapPath given in asp.net

Good explanation:- What is the equivalent of Server.MapPath in ASP.NET Core?

//this code from above link that how it will be used in the code
public class HomeController : Controller
{
    private readonly IHostingEnvironment _hostingEnvironment;

    public HomeController(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

    public ActionResult Index()
    {
        string webRootPath = _hostingEnvironment.WebRootPath;
        string contentRootPath = _hostingEnvironment.ContentRootPath;

        return Content(webRootPath + "\n" + contentRootPath);
    }
}

This is the actual code which gives me the error, I replace the WebRootPath with another way to solve the issue and it works. you can assign and use in the entire application.

public async Task<ActionResult> SaveAsync(IEnumerable<IFormFile> files)
        {
            // The Name of the Upload component is "files"
            if (files != null)
            {
                foreach (var file in files)
                {
                    var fileContent = ContentDispositionHeaderValue.Parse(file.ContentDisposition);

                    // Some browsers send file names with full path.
                    // We are only interested in the file name.
                    var fileName = Path.GetFileName(fileContent.FileName.ToString().Trim('"'));

                    //The below line gives the error
                    //var physicalPath = Path.Combine(HostingEnvironment.WebRootPath, "App_Data", fileName);

                    //and I replace with this (but we can use this variable at multiple location by assign a physical path)
                    var physicalPath = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"), "App_Data", fileName);

                    //The files are not actually saved in this demo
                    using (var fileStream = new FileStream(physicalPath, FileMode.Create))
                    {
                        await file.CopyToAsync(fileStream);
                    }
                }
            }

            // Return an empty string to signify success
            return Content("");
        }
Ajay2707
  • 5,345
  • 6
  • 34
  • 52
0

I was faced with the same issue but with what seems a unique scenario to this post, so I'll add it.

I have a solution with several nested projects. Similar to this:

> Solution
  > MvcProject
    > wwwroot
    > // etc.
  > SecondMvcProject
  > AnotherMvcProject

When running my MvcProject, the IHostingEnvironment had the ContentRootPath set to the Solution folder, and the WebRootPath was null.

Per other people's answers, adding a wwwroot folder in the Solution folder made WebRootPath have a value, but it was the Solution folder path. I had to modify my launch task's current working directory (cwd) in VS Code. It defaulted to "cwd": "${workspaceFolder}", and I had to change it to "cwd": "${workspaceFolder}/MvcProject"

Update

I had this same problem again on another machine, and was glad I commented on this. This time, the problem was that we didn't have any files in one of our wwwroot folders, and empty folders don't get committed to git repos. Add a file to your folder, if you need it!

(It was there for consistency with setup for static file handling. We'll eventually have something in there before the project launches!)

ps2goat
  • 7,102
  • 1
  • 28
  • 59