Home > OS >  How Can I get the real name of an image from a url
How Can I get the real name of an image from a url

Time:11-28

I have the next url about an image:

https://i.discogs.com/HE17wcv1sG6NDK1WcVyoQjSqUGDZva3SYvm6vXoCMOo/rs:fit/g:sm/q:90/h:600/w:600/czM6Ly9kaXNjb2dz/LWRhdGFiYXNlLWlt/YWdlcy9SLTk2OTY5/NjktMTQ4NDkzNzkw/Ni00MDcyLmpwZWc.jpeg

If I open the url with the navigator and then I press de right button to save this image in my hard disc the name solved by the navigator for this file image is distinct. How can i get the last name of the file in c#?

CodePudding user response:

If you're set on using WebClient then you can download the data into memory, check for the Content-Disposition header, and then change the filename accordingly. I've added commented out parts that you can use instead of their synchronous counterparts if you're using this method asynchronously.

// private static async Task DownloadImageAsync(string url, string folder)
private static void DownloadImage(string url, string folder)
{
    var uri = new Uri(url);
    string fileName = Path.GetFileName(uri.AbsolutePath);
    WebClient client = new WebClient();
    // byte[] fileData = await client.DownloadDataTaskAsync(url);
    byte[] fileData = client.DownloadData(url);

    string disposition = client.ResponseHeaders.Get("Content-Disposition"); // try to get the disposition
    if (!string.IsNullOrEmpty(disposition) // check it has a value
        && ContentDispositionHeaderValue.TryParse(disposition, out var parsedDisposition) // check it can be parsed
        && !string.IsNullOrEmpty(parsedDisposition.FileName)) // check a filename is specified
    {
        fileName = parsedDisposition.FileName.Trim('"'); // replace the normal filename with the parsed one
    }
    // await File.WriteAllBytesAsync(Path.Combine(folder, fileName), fileData);
    File.WriteAllBytes(Path.Combine(folder, fileName), fileData);
}

Usage: DownloadImage(myurl, @"C:\Users\Me\Desktop");


That said, WebClient is a bit old-fashioned and you should probably use HttpClient for newer developments:

private static async Task DownloadImageAsync(string url, string folder)
{
    var uri = new Uri(url);
    string fileName = Path.GetFileName(uri.AbsolutePath);

    using var response = await _httpClient.GetAsync(url);
    response.EnsureSuccessStatusCode();

    if (!string.IsNullOrEmpty(response.Content.Headers.ContentDisposition?.FileName))
    {
        fileName = response.Content.Headers.ContentDisposition.FileName.Trim('"');
    }

    using var outputFile = File.Create(Path.Combine(folder, fileName));
    await response.Content.CopyToAsync(outputFile);
}

Usage: await DownloadImageAsync(myurl, @"C:\Users\Me\Desktop");

Microsoft recommend using a single static instance of HttpClient throughout your application (docs). This does have pitfalls though, so depending on your application, you might want to look into using IHttpClientFactory, which works to solve the issues that come from using a static HttpClient.

  • Related