如何解析 ASP.NET Core 3 中的本地文件路径?

Ema*_*ele 4 c#

我使用的Visual Studio Code版本1.42Ubuntu 18.04。我刚刚sudo dotnet add package Google.Apis.Drive.v3通过终端成功安装,但我找不到System.Web在我的C#项目上安装的方法。在做了一些研究之后,我发现了这个,它基本上解释了,我需要访问一个IHostingEnvironment env objectASP.NET Core 会处理的。

我在解析本地文件路径时遇到问题。我的问题是我不熟悉这种类型的方法,想问问,鉴于下面的代码,有人可以告诉我如何修改它以使用IHostingEnvironment env object.

问题出现在包含以下内容的行中:

HttpContext.Current.Server.MapPath("~/GoogleDriveFiles")
Run Code Online (Sandbox Code Playgroud)

这是代码的其余部分:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止我做了什么:

1)我浏览了这篇文章作为基本解释,但这并没有解决我的问题。

2)这篇文章作为基本方法在某种程度上也很有用。有用,但仍然无法弄清楚我缺少什么。

3)我对问题进行了更多的挖掘并到达了这里,但仍然没有运气。

非常感谢您指出正确的方向。

Pan*_*vos 14

您不需要System.Web或 HttpContext。你可以阅读从Web应用程序的根路径IHostingEnvironment.WebRootPath在ASP.NET核心2.x或IWebHostEnvironment.WebPath在ASP.NET核心3.x中

依赖注入机制知道该接口,这意味着您可以将其作为依赖项添加到控制器或服务中,例如:

public class MyController : Controller 
{
    private IWebHostEnvironment _hostingEnvironment;

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

    [HttpGet]
    public IActionResult Get() {

        var path = Path.Combine(_hostingEnvironment.WebRootPath, "GoogleDriveFiles");
        ...
    }
Run Code Online (Sandbox Code Playgroud)

您可以将根路径传递给类的构造函数。毕竟,一个名为的类GoogleDriveFilesRepository只关心它的本地文件夹,而不关心它是否托管在 Web 或控制台应用程序上。对于工作,方法应该没有是静态的:

public class GoogleDriveFilesRepository 
{

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

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

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

}
Run Code Online (Sandbox Code Playgroud)

您可以在 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);
        });
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这个类现在可以用作对控制器的依赖。不再需要IWebHostEnvironment在控制器中使用:

public class MyController : Controller 
{
    private GoogleDriveFilesRepository _gdrive;

    public MyController(GoogleDriveFilesRepository gdrive) {
        _gdrive=gdrive;
    }
}
Run Code Online (Sandbox Code Playgroud)

依赖注入的好处是如果做得对,类本身不需要知道使用了 DI。MyContainer并且GoogleDriveFilesRepository可以用于例如单元测试而无需设置 DI :

[Fact]
public void Just_A_Test()
{
    var repository=new GoogleDriveFilesRepository("sometestpath");
    var myController=new MyController(repository);
    myController.DoTheUpload(...);
}
Run Code Online (Sandbox Code Playgroud)