web-dev-qa-db-ja.com

Server.MapPathの代替方法であるASP.Net Coreで絶対パスを取得する方法

Server.MapPathのASPネットコア代替方法で絶対パスを取得する方法

IHostingEnvironmentを使用しようとしましたが、適切な結果が得られません。

IHostingEnvironment env = new HostingEnvironment();
var str1 = env.ContentRootPath; // Null
var str2 = env.WebRootPath; // Null, both doesn't give any result 

wwwrootフォルダーに1つの画像ファイル(Sample.PNG)があり、この絶対パスを取得する必要があります。

26
Shanmu_92

依存クラスとしてIHostingEnvironmentを依存クラスに注入します。フレームワークはあなたのためにそれを埋めます

public class HomeController : Controller {
    private IHostingEnvironment _hostingEnvironment;

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

    [HttpGet]
    public IActionResult Get() {
        var path = Path.Combine(_hostingEnvironment.WebRootPath, "Sample.PNG");
        return View();
    }
}

さらに一歩進んで、独自のパスプロバイダーサービスの抽象化と実装を作成できます。

public interface IPathProvider {
    string MapPath(string path);
}

public class PathProvider : IPathProvider {
    private IHostingEnvironment _hostingEnvironment;

    public PathProvider(IHostingEnvironment environment) {
        _hostingEnvironment = environment;
    }

    public string MapPath(string path) {
        var filePath = Path.Combine(_hostingEnvironment.WebRootPath, path);
        return filePath;
    }
}

そして、IPathProviderを依存クラスに注入します。

public class HomeController : Controller {
    private IPathProvider pathProvider;

    public HomeController(IPathProvider pathProvider) {
        this.pathProvider = pathProvider;
    }

    [HttpGet]
    public IActionResult Get() {
        var path = pathProvider.MapPath("Sample.PNG");
        return View();
    }
}

サービスをDIコンテナに登録してください

services.AddSingleton<IPathProvider, PathProvider>();
74
Nkosi

*ハック*推奨されませんが、参考までにvar abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\","");を使用して相対パスから絶対パスを取得できます

上記のDI/Serviceアプローチをお勧めしますが、DI以外の状況(たとえば、Activatorでインスタンス化されたクラス)の場合、これは機能します。

5
Randy Buchholz

より良い解決策は、IFileProvider.GetFileInfo()メソッドを使用することです。

    public IActionResult ResizeCat([FromServices] IFileProvider fileProvider)
    {
        // get absolute path (equivalent to MapPath)
        string absolutePath = fileProvider.GetFileInfo("/assets/images/cat.jpg").PhysicalPath;  
        ... 
    }

登録する必要がありますIFileProviderDI経由でアクセスできるようにするには

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc();

        var physicalProvider = _hostingEnvironment.ContentRootFileProvider;
        var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
        var compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);

        // choose one provider to use for the app and register it
        //services.AddSingleton<IFileProvider>(physicalProvider);
        //services.AddSingleton<IFileProvider>(embeddedProvider);
        services.AddSingleton<IFileProvider>(compositeProvider);
    }

ご覧のとおり、このロジック(ファイルの出所)は非常に複雑になる可能性がありますが、コードが変更されても壊れることはありません。

特別なロジックがある場合は、new PhysicalFileProvider(root)でカスタムIFileProviderを作成できます。ミドルウェアに画像をロードし、サイズ変更またはトリミングしたい状況がありました。しかし、それはAngularプロジェクトなので、デプロイされたアプリのパスは異なります。私が書いたミドルウェアはstartup.csからIFileProviderを取り、それから過去にMapPathを使用していたようにGetFileInfo()を使用できます。

3
Simon_Weaver

@NKosiに感謝しますが、IHostingEnvironmentはMVCコア3で廃止されました!!

this に従って:

廃止されたタイプ(警告):

Microsoft.Extensions.Hosting.IHostingEnvironment
Microsoft.AspNetCore.Hosting.IHostingEnvironment
Microsoft.Extensions.Hosting.IApplicationLifetime
Microsoft.AspNetCore.Hosting.IApplicationLifetime
Microsoft.Extensions.Hosting.EnvironmentName
Microsoft.AspNetCore.Hosting.EnvironmentName

新しいタイプ:

Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
Microsoft.Extensions.Hosting.IHostApplicationLifetime
Microsoft.Extensions.Hosting.Environments 

したがって、IWebHostEnvironmentの代わりにIHostingEnvironmentを使用する必要があります。

public class HomeController : Controller
{
    private readonly IWebHostEnvironment _webHostEnvironment;

    public HomeController(IWebHostEnvironment webHostEnvironment)
    {
        _webHostEnvironment= webHostEnvironment;
    }

    public IActionResult Index()
    {
        string webRootPath = _webHostEnvironment.WebRootPath;
        string contentRootPath = _webHostEnvironment.ContentRootPath;

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