使用 EF7 命令时,IHostingEnvironment.WebRootPath 为空

Posted

技术标签:

【中文标题】使用 EF7 命令时,IHostingEnvironment.WebRootPath 为空【英文标题】:IHostingEnvironment.WebRootPath is null when using EF7 commands 【发布时间】:2016-02-10 17:37:16 【问题描述】:

问题

当我尝试向我的代码添加迁移时,例如:dnx ef migrations add initial

Startup(IHostingEnvironment env) 中的env.WebRootPath 为空。

这会在添加新迁移或更新数据库时出现编译错误。

守则

Startup.cs 类中,我在构造函数中有这些行:

public Startup(IHostingEnvironment env)

    // ...
    MyStaticClass.Initialize(env.WebRootPath);
    // ...
    _hostingEnvironment = env;

这里env.WebRootPath 为空,而在Initialize 函数中这会引发异常。

Startup.csConfigureServices 函数中,我解决了我的类依赖项:

public void ConfigureServices(IServiceCollection services)

    // ...
    services.AddInstance<IMyService>(new MyService(_hostingEnvironment.WebRootPath))
    // Note: _hostingEnvironment is set in the Startup constructor.
    // ...

备注

我可以很好地构建、运行和部署代码。一切正常!

但是,我对模型进行了更改,并希望使用以下命令添加迁移:dnx ef migrations add MyMigration 然后我在包管理器控制台中看到编译错误。

我正在使用 ASP 5 Web 应用程序和 Entity Framework 7

【问题讨论】:

我在我的应用程序中添加了 wwwroot 文件夹,它运行良好。 【参考方案1】:

如果 wwwroot 文件夹被无意中从项目的根目录中删除,则 env.WebRootPath 也可以为空。将 wwwroot 文件夹添加到项目的根目录也可以解决此问题。

【讨论】:

【参考方案2】:

关于我的问题在 github 上报告了一个问题:

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

我在 cmets 中使用了解决方法,现在它似乎工作正常:

if (string.IsNullOrWhiteSpace(_env.WebRootPath))

   env.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");

【讨论】:

Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "wwwroot");【参考方案3】:

我相信这个帖子是找出这个问题的答案的最佳人选。

方法一:

我花了一些时间寻找答案,我发现解决这个问题而不是检查路径是否存在(在控制器或方法中)的方法是更新您的 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>();

这样您将确保有 webroot 文件夹准备好在其中放置文件,并且 _environment.webRootPath 不会为空,您甚至可以自定义文件夹的名称。

方法二

执行此操作的第二个选项是从 Visual Studio 级别在项目中手动添加“wwwroot”文件夹。程序应将其拾取并分配为 wwwroot 文件夹:

【讨论】:

对我来说,通过添加.UseWebRoot("wwwroot") 解决了这个问题。谢谢。【参考方案4】:

在我的情况下,问题是 wwwroot 文件夹是空的,VS 没有识别它。

解决办法:在wwwroot中创建一个placeholder.txt。

希望对你有帮助。

【讨论】:

如果 wwwroot 文件夹为空,则 env.WebRootPath 变量为空。【参考方案5】:

我在使用 Telerik 控件的 asp.net 核心应用程序中上传文件时遇到错误。该错误与 Telerik 控制无关。

在调查时,我得到的描述是,这是与asp.net 中给出的Server.MapPath 提供相同功能的变量

很好的解释:-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);
    

这是给我错误的实际代码,我用另一种解决问题的方法替换了 WebRootPath 并且它有效。您可以在整个应用程序中分配和使用。

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

【讨论】:

【参考方案6】:

我也遇到了同样的问题,但这篇文章似乎是一个独特的场景,所以我会添加它。

我有一个包含多个嵌套项目的解决方案。类似这样:

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

运行我的MvcProject 时,IHostingEnvironmentContentRootPath 设置为Solution 文件夹,而WebRootPath 为空。

根据其他人的回答,在Solution 文件夹中添加wwwroot 文件夹使WebRootPath 具有值,但它是Solution 文件夹路径。我不得不在 VS Code 中修改启动任务的当前工作目录 (cwd)。默认为"cwd": "$workspaceFolder",我只好改成"cwd": "$workspaceFolder/MvcProject"

更新

我在另一台机器上又遇到了同样的问题,很高兴我对此发表了评论。这一次,问题是我们的wwwroot 文件夹之一中没有任何文件,并且空文件夹不会被提交到 git repos。如果需要,将文件添加到您的文件夹!

(它的存在是为了与静态文件处理的设置保持一致。我们最终会在项目启动之前在那里找到一些东西!)

【讨论】:

【参考方案7】:

如果有人仍然面临这个问题,就我而言,问题是我为测试创建的默认构造函数。

所以,如果有的话,删除默认构造函数。

【讨论】:

以上是关于使用 EF7 命令时,IHostingEnvironment.WebRootPath 为空的主要内容,如果未能解决你的问题,请参考以下文章

asp.net core 使用EF7 Code First 创建数据库,同时使用命令创建数据库(本来想数据迁移 没有成功,只能将标题搞成这个。)

EF7 alpha 连接状态问题

ASP.NET Mvc5+EF7

EF7DbContext池

EF7 如何处理嵌套实体的更新操作

ASP.NET vNext EF7 dbContext 问题