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)があり、この絶対パスを取得する必要があります。
依存クラスとして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>();
*ハック*推奨されませんが、参考までにvar abs = Path.GetFullPath("~/Content/Images/Sample.PNG").Replace("~\\","");
を使用して相対パスから絶対パスを取得できます
上記のDI/Serviceアプローチをお勧めしますが、DI以外の状況(たとえば、Activator
でインスタンス化されたクラス)の場合、これは機能します。
より良い解決策は、IFileProvider.GetFileInfo()
メソッドを使用することです。
public IActionResult ResizeCat([FromServices] IFileProvider fileProvider)
{
// get absolute path (equivalent to MapPath)
string absolutePath = fileProvider.GetFileInfo("/assets/images/cat.jpg").PhysicalPath;
...
}
登録する必要がありますIFileProvider
DI経由でアクセスできるようにするには :
// 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()
を使用できます。
@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);
}
}