Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I resolve a local file path in ASP.NET Core 3?

Tags:

c#

I am using Visual Studio Code version 1.42 on my Ubuntu 18.04. I just successfully installed sudo dotnet add package Google.Apis.Drive.v3 via terminal but I can't find a way to install System.Web on my C# project. After doing some research I came across this which explains that basically, I need to access a IHostingEnvironment env object, that ASP.NET Core will take care of.

The problem I'm having trouble resolving local file paths. I have is that I am not familiar with this type of approach and wanted to ask if, given the code below, someone could show me how to modify it to use a IHostingEnvironment env object.

The problem appears in the lines that contain :

HttpContext.Current.Server.MapPath("~/GoogleDriveFiles")

This is the rest of the code :

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
//using System.Web;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;


namespace WebApi2.Models
{
    public class GoogleDriveFilesRepository 
    {
       //defined scope.
        public static string[] Scopes = { DriveService.Scope.Drive };
        // Operations....

        //create Drive API service.
        public static DriveService GetService()
        {
             //Operations.... 

        public static List<GoogleDriveFiles> GetDriveFiles()
        {
            // Other operations....
        }

       //file Upload to the Google Drive.
        public static void FileUpload(HttpPostedFileBase file) // <-- Error here
        {
            if (file != null && file.ContentLength > 0)
            {
                DriveService service = GetService();

                string path = Path.Combine(HttpContext.Current.Server.MapPath("~/GoogleDriveFiles"), // <-- Error here
                Path.GetFileName(file.FileName));
                file.SaveAs(path);

                var FileMetaData = new Google.Apis.Drive.v3.Data.File();
                FileMetaData.Name = Path.GetFileName(file.FileName);
                FileMetaData.MimeType = MimeMapping.GetMimeMapping(path); // <-- Error here

                FilesResource.CreateMediaUpload request;

                using (var stream = new System.IO.FileStream(path, System.IO.FileMode.Open))
                {
                    request = service.Files.Create(FileMetaData, stream, FileMetaData.MimeType);
                    request.Fields = "id";
                    request.Upload();
                }
            }
        }


        //Download file from Google Drive by fileId.
        public static string DownloadGoogleFile(string fileId)
        {
            DriveService service = GetService();

            string FolderPath = System.Web.HttpContext.Current.Server.MapPath("/GoogleDriveFiles/"); // <-- Error here
            FilesResource.GetRequest request = service.Files.Get(fileId);

            string FileName = request.Execute().Name;
            string FilePath = System.IO.Path.Combine(FolderPath, FileName);

            MemoryStream stream1 = new MemoryStream();

            request.MediaDownloader.ProgressChanged += (Google.Apis.Download.IDownloadProgress progress) =>
            {
                switch (progress.Status)
                {
                    case DownloadStatus.Downloading:
                        {
                            Console.WriteLine(progress.BytesDownloaded);
                            break;
                        }
                    case DownloadStatus.Completed:
                        {
                            Console.WriteLine("Download complete.");
                            SaveStream(stream1, FilePath);
                            break;
                        }
                    case DownloadStatus.Failed:
                        {
                            Console.WriteLine("Download failed.");
                            break;
                        }
                }
            };
            request.Download(stream1);
            return FilePath;
        }
    }
}

What I have done so far:

1) I went through this post as basic explanation but that didn't resolve the issue I have.

2) This post too was somehow useful as basic approach. Useful but still can't figure out what I am missing.

3) I dug more into the problem and arrived here but still no luck.

Thank you very much for pointing to the right direction.

like image 602
Emanuele Avatar asked Feb 28 '20 16:02

Emanuele


People also ask

How do I get wwwroot path in .NET Core?

The path of the wwwroot folder is accessed using the interfaces IHostingEnvironment (. Net Core 2.0) and IWebHostEnvironment (. Net Core 3.0) in ASP.Net Core. The IHostingEnvironment is an interface for .

How do I serve a static file in NET Core?

Serve static filesStatic files are stored within the project's web root directory. The default directory is {content root}/wwwroot , but it can be changed with the UseWebRoot method. For more information, see Content root and Web root. The preceding code was created with the web app template.

How do I get a full file path?

Click the Start button and then click Computer, click to open the location of the desired file, hold down the Shift key and right-click the file. Copy As Path: Click this option to paste the full file path into a document. Properties: Click this option to immediately view the full file path (location).


1 Answers

You don't need System.Web or HttpContext. You can read the web app's root path from IHostingEnvironment.WebRootPath in ASP.NET Core 2.x, or IWebHostEnvironment.WebPath in ASP.NET Core 3.x.

The dependency injection mechanism knows about that interface which means you can add it as a dependency to your controllers or services, eg :

public class MyController : Controller 
{
    private IWebHostEnvironment _hostingEnvironment;

    public MyController(IWebHostEnvironment environment) {
        _hostingEnvironment = environment;
    }

    [HttpGet]
    public IActionResult Get() {

        var path = Path.Combine(_hostingEnvironment.WebRootPath, "GoogleDriveFiles");
        ...
    }

You can pass the root path to your class's constructor. After all, a class named GoogleDriveFilesRepository only cares about its local folder, not whether it's hosted on a web or console application. For that to work, the methods should not be static:

public class GoogleDriveFilesRepository 
{

    public GoogleDriveFilesRepository (string rootPath)
    {
        _rootPath=rootPath;
    }

    public DriveService GetService()
    {
         //Operations.... 

    public List<GoogleDriveFiles> GetDriveFiles()
    {
        // Other operations....
    }

}

You can register that class as a service in Startup.cs :

public class Startup
{
    private readonly IWebHostEnvironment _env;

    public Startup(IConfiguration configuration, IWebHostEnvironment env)
    {
        Configuration = configuration;
        _env = env;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignleton<GoogleDriveFilesRepository>(_ =>{
            var gdriveRoot=Path.Combine(_env.WebRootPath,"GoogleDriveFiles");
            return new GoogleDriveFilesRepository(gdrivePath);
        });
        ...
    }
}

This class can now be used as a dependency on a controller. It's no longer necessary to use IWebHostEnvironment in the controller :

public class MyController : Controller 
{
    private GoogleDriveFilesRepository _gdrive;

    public MyController(GoogleDriveFilesRepository gdrive) {
        _gdrive=gdrive;
    }
}

The nice thing with dependency injection is that if done right, the classes themselves don't need to know that DI is used. MyContainer and GoogleDriveFilesRepository can be used in eg a unit test without having to setup DI :

[Fact]
public void Just_A_Test()
{
    var repository=new GoogleDriveFilesRepository("sometestpath");
    var myController=new MyController(repository);
    myController.DoTheUpload(...);
}
like image 110
Panagiotis Kanavos Avatar answered Oct 04 '22 18:10

Panagiotis Kanavos