Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.Net Core 2.0 - Retrieve Image Url

I am trying to create a restful service that exposes some data, everything was just fine until I realize is a pain to expose images full URL from the server. Maybe it's just me but I am finding it very complicated.

Just to be in context, I am using Entity Framework to read from my Database, here is the table I am working with:

enter image description here

As you can see, there is a field named "ImagePath", bad name guys, it should be "ImageName", whatever, that column is saving the exact file name of the image that represents that Champion object, all the images are currently located inside the wwwroot project folder, just like this:

enter image description here

All the Business Logic is not at the controller, is at a Service folder/layer in a regular class (Maybe this is not relevant, but I just wanted to clarify I am not working inside any controller):

enter image description here

And this is the method where I expect the magic to happen:

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;
}

Just to be clear here, the key line here is:

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

I need to somehow get the current URL just like in the example to add it to every single champion so it can be used by the client side inside an image tag.

If it is not possible to do it by the approach I am trying to implement I will accept any other suggestion, the point here is to expose the Image URL, does not matter how.

like image 907
José Caballero Avatar asked May 22 '18 06:05

José Caballero


1 Answers

Basically, you need to use IHostingEnvironment and inject it in your service constructor. Then create a string variable with the name of your folder inside the wwwroot let's say "Champions"

Here's the example code:

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;
}

What IHostingEnvironment interface does is "Provides information about the hosting environment an application is running in."

If you want to get files inside a given path, this will give you a hint.

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

foreach (var item in directoryFiles)
{
    // do something here
}

If you want to create path link from those wwwroot folder, you need register in your startup the UseDirectoryBrowser

Inside your Startup.cs file, Find the Configure method insert this code snippet

These code snippets will expose files inside the Champions directory and create a new route on your website which is ChampionImages derived from folder Champions in your wwwroot

app.UseDirectoryBrowser(new DirectoryBrowserOptions()
{
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot", "Champions")),
    RequestPath = new PathString("/ChampionImages")
});

Then you can now use something like this localhost:8080/ChampionImages where you can see each file stored inside the Champions folder of your wwwroot. What you can do to create a URL of that image is something like this.

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

I hope this simple code snippets give you help or idea :)

like image 182
mark333...333...333 Avatar answered Sep 19 '22 13:09

mark333...333...333