web-dev-qa-db-ja.com

EF7コマンドを使用すると、IHostingEnvironment.WebRootPathがnullになる

問題

コードに移行を追加しようとすると、たとえば、_dnx ef migrations add initial_、

Startup(IHostingEnvironment env)の_env.WebRootPath_がnullです。

これにより、新しい移行を追加したり、データベースを更新したりすると、コンパイルエラーが発生します。

コード

Startup.csクラスでは、コンストラクターに次の行があります。

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

ここで_env.WebRootPath_はnullであり、Initialize関数ではこれにより例外がスローされます。

ConfigureServices関数のStartup.csで、クラスの依存関係を解決します:

_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を使用しています。

11
A-Sharabiani

私の問題に関してgithubで報告された問題があります:

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

コメントで回避策を使用しましたが、うまく機能しているようです:

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

プロジェクトのルートからwwwrootフォルダーが誤って削除された場合も、env.WebRootPathをnullにすることができます。プロジェクトのルートにwwwrootフォルダを追加すると、この問題も修正されます。

33
Ricky Keane

私の場合、問題はwwwrootフォルダーが空で、VSがそれを認識しないことでした。

解決策:wwwrootにplaceholder.txtを作成します。

それが役に立てば幸い。

私は同じ問題に直面しましたが、この投稿には独特のシナリオのように見えるので、追加します。

いくつかのネストされたプロジェクトを持つソリューションがあります。これに似ています:

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

私のMvcProjectを実行すると、IHostingEnvironmentContentRootPathSolutionフォルダーに設定し、WebRootPathはnullでした。

他の人の答えによれば、wwwrootフォルダーにSolutionフォルダーを追加すると、WebRootPathに値が設定されますが、これはSolutionフォルダーパスでした。 VS Codeで起動タスクの現在の作業ディレクトリ(cwd)を変更する必要がありました。デフォルトは"cwd": "${workspaceFolder}"で、"cwd": "${workspaceFolder}/MvcProject"に変更する必要がありました。

更新

別のマシンでも同じ問題が発生したので、コメントしてくれて嬉しかったです。今回は、wwwrootフォルダーのいずれにもファイルがなく、空のフォルダーがgitリポジトリにコミットされないことが問題でした。必要に応じて、ファイルをフォルダーに追加します。

(静的ファイル処理の設定との一貫性のためにありました。プロジェクトが開始する前に、最終的にはそこに何かがあるでしょう!)

0
ps2goat

誰かがまだこの問題に直面している場合、私の場合、問題は私がテスト用に作成したデフォルトのコンストラクタでした。

したがって、デフォルトのコンストラクタがあれば削除します。

0
M.Nour Berro

このスレッドは、この問題の答えを見つけるのに最適なスレッドです。

方法1:

私は少し時間をかけて答えを探していましたが、(コントローラーまたはメソッドに)パスが存在するかどうかを確認するのではなく、これを整理する方法は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がnullにならず、フォルダーの名前をカスタマイズすることもできます。

方法2

これを行う2番目のオプションは、Visual Studioレベルからプロジェクトに「wwwroot」フォルダーを手動で追加することです。プログラムはこれを取得し、wwwrootフォルダとして割り当てる必要があります。

Method no 2

0

Telerikコントロールを使用したasp.netコアアプリケーションでのファイルのアップロード中にエラーが発生しました。エラーはTelerikの制御とは関係ありません。

調査中に、これはServer.MapPathで提供されるasp.netと同じ機能を提供する変数であるという説明を得ました

良い説明:- ASP.NET CoreのServer.MapPathに相当するもの

//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("");
        }
0
Ajay2707