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:
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:
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):
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.
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With