ASP.NET Core 2.0 - 获取图片URL

12

我正在尝试创建一个restful服务来公开一些数据,一切都很顺利,直到我意识到从服务器暴露图像的完整URL是一件痛苦的事情。也许只有我觉得很复杂。

为了更好地理解背景,我正在使用Entity Framework从我的数据库中读取数据,这是我正在处理的表:

enter image description here

正如你所看到的,有一个名为“ImagePath”的字段,命名不好,应该是“ImageName”,但那列保存了代表Champion对象的图片的确切文件名,所有图片当前位于wwwroot项目文件夹内,就像这样:

enter image description here

所有业务逻辑都不在控制器中,而是在一个常规类的Service文件夹/层中(也许这不是相关的,但我只想澄清我没有在任何控制器中工作):

enter image description here

这是我期望魔术发生的方法:

public async Task<IList<Champion>> GetChampions()
{
   List<Champion> champions = await _context.Champion
   .Include(x => x.PrimaryClass)
   .Include(x => x.SecondaryClass)
   .Include(x => x.ChampionUserRate)
   .ToListAsync();

   //BEFORE RETURNING THE CHAMPION TO THE CONTROLLER, I WILL NEED TO CONCATENATE MY CURRENT SERVER URL AND THE PATH TO THE IMAGE PLUS THE IMAGE NAME FILE WHICH IS ALREADY IN THE DATABASE AND ALREADY MATCHES THE IMAGES FOLDER

   string serverPathToChampionsFolder = null; //Example: http://localhost:57435/wwwroot/Champions

   foreach (var champion in champions)
   {
       champion.ImagePath = serverPathToChampionsFolder + champion.ImagePath;
   }

return champions;
}

在这里需要明确的是,关键行是:

 string serverPathToChampionsFolder = null; //Example: http://localhost:57435/wwwroot/Champions

我需要以类似于示例的方式获取当前URL,以便将其添加到每个冠军上,以便客户端可以在图像标记中使用它。

如果无法通过我尝试实现的方法来实现它,那么我将接受任何其他建议,重点是公开图像URL,不管怎样都可以。


4
一个简单的方法是将URL存储在appsettings.json中,并将设置对象注入到您的服务构造函数中。你认为呢? - Ignas
3
继续@Brad的话题,如果应用程序不在根路径上,则使用Url.Content($"~/Champions/{filename}");使其正常工作。 - RMH
这个服务类从哪里被调用了? - Brad
2个回答

11

基本上,您需要使用 IHostingEnvironment 并将其注入到服务构造函数中。然后创建一个名为您的文件夹的字符串变量,位于 wwwroot 中,比如说 "Champions"

以下是示例代码:

private readonly IHostingEnvironment hostingEnv;

private const string ChampionsImageFolder = "Champions";

public ChampionsService(IHostingEnvironment hostingEnv){
    this.hostingEnv = hostingEnv;
}

// Suppose this method is responsible for fetching image path
public string GetImage(){
    var path = Path.Combine(hostingEnv.WebRootPath, ChampionsImageFolder);

    return path;
}

IHostingEnvironment 接口的作用是"提供有关应用程序正在运行的托管环境的信息。"

如果您想获取给定路径中的文件,这将为您提供提示。

var directoryFiles = Directory.GetFiles("wwwroot/Champions");

foreach (var item in directoryFiles)
{
    // do something here
}
如果您想从这些wwwroot文件夹创建路径链接,您需要在启动中注册UseDirectoryBrowser
在您的Startup.cs文件中,找到Configure方法并插入此代码片段。
这些代码片段将公开Champions目录中的文件,并在您的网站上创建一个新路由,即从wwwroot文件夹中的Champions派生的ChampionImages
app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "Champions")),
    RequestPath = new PathString("/ChampionImages")
});

那么现在您可以使用类似于 localhost:8080/ChampionImages 的东西,您可以在其中查看存储在wwwroot的Champions文件夹内的每个文件。您可以执行以下操作来创建该图像的URL。

var imageUrl = $"/ChampionImages/{exactFileName}"; // this will create a string link.

我希望这段简单的代码片段能为您提供帮助或灵感 :)


1
这样做不会给出文件的完整操作系统路径吗?你不想把它放在图像标签中。我相信OP想要URL。 - Brad
@Brad 我添加了另一个提示 - mark333...333...333
我明白了。好的,他需要在启动时注册静态文件和目录浏览器 @Brad - mark333...333...333
1
如果我们假设 OP 已经有了 app.UseStaticFiles(),那么他的 wwwroot/Champions 文件夹已经被公开,所以你添加的内容是完全不必要的。它如何帮助他将 URL 前缀添加到图像 URL 属性中呢? - Brad
我遇到了同样的问题,这个方法只能看到文件夹结构,但是当我尝试访问文件时,会显示404错误。你能帮忙解决吗? - neena
显示剩余8条评论

1
// Enable directory browsing
            app.UseStaticFiles();
            app.UseStaticFiles(new StaticFileOptions()
            {
                FileProvider = new PhysicalFileProvider(
           Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),
                RequestPath = new PathString("/images")
            });
         
            app.UseDirectoryBrowser(new DirectoryBrowserOptions()
            {
                FileProvider = new PhysicalFileProvider(
            Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),
                RequestPath = new PathString("/images")
            });

上面的答案是正确的,但仍然无法加载图像URL,因此需要在startup.cs文件中添加几行代码,我在这里发布


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接