1

The struggle is real. Somehow I can't download this image

string url = @"https://valgfrigave.dk/image/cache/catalog/200%20kr./Lyngby-glas-whiskey01_1000X1000px_200kr-750x750.jpg";

The return error is

 The remote server returned an error: (404) Not Found.

But if you post the url into a browser, you'll get these whiskey glasses enter image description here

I've been using WebClient and HttpWebRequest. Tried all of the suggestions an answers from

How do I programmatically save an image from a URL?

https://social.msdn.microsoft.com/Forums/en-US/d77b3c9a-d453-4622-8639-b7f0f91ecc9a/save-image-from-given-url?forum=csharpgeneral

https://forgetcode.com/CSharp/2052-Download-images-from-a-URL

https://www.codeproject.com/Articles/24920/C-Image-Download

https://social.msdn.microsoft.com/Forums/vstudio/en-US/c3289e1b-56aa-49b8-8c62-feaaf51cd0a2/download-images-from-url?forum=csharpgeneral

(...and alot more...)

But none of them is able to download the image.

EDIT

Below is the code where I try to download the image. The error occurs at client.OpenRead(innUri):

class Program
{
    static void Main(string[] args)
    {
        string url = @"https://valgfrigave.dk/image/cache/catalog/200%20kr./Lyngby-glas-whiskey01_1000X1000px_200kr-750x750.jpg";
        string fileFullPath = @"C:\TEMP\Image.jpg";

        using (WebClient client = new WebClient())
        {
            Uri innUri = null;
            Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out innUri);

            try
            {
                client.Headers.Add("Accept-Language", "en-US");
                client.Headers.Add("Accept-Encoding", "gzip, deflate");
                client.Headers.Add("Accept", " text/html, application/xhtml+xml, */*");
                client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");

                using (Stream stream = client.OpenRead(innUri))
                {
                    using (System.IO.FileStream output = new System.IO.FileStream(fileFullPath, FileMode.Create))
                    {
                        byte[] buffer = new byte[16 * 1024]; // Fairly arbitrary size
                        int bytesRead;

                        while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            output.Write(buffer, 0, bytesRead);
                        }
                    }
                }
            }
            catch (WebException we)
            {
                throw we;
            }
        } 
    }
}

2nd EDIT

Still doesn't work after trying the suggested approach enter image description here

SOLUTION

A solution has been found and can be seen by the comment from @Stephan Schlecht. Added the following method and replaced the URI creation:

Method added:

public static Uri MyUri(string url)
{
    Uri uri = new Uri(url);
    System.Reflection.MethodInfo getSyntax = typeof(UriParser).GetMethod("GetSyntax", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
    System.Reflection.FieldInfo flagsField = typeof(UriParser).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
    if (getSyntax != null && flagsField != null)
    {
        foreach (string scheme in new[] { "http", "https" })
        {
            UriParser parser = (UriParser)getSyntax.Invoke(null, new object[] { scheme });
            if (parser != null)
            {
                int flagsValue = (int)flagsField.GetValue(parser);
                // Clear the CanonicalizeAsFilePath attribute
                if ((flagsValue & 0x1000000) != 0)
                    flagsField.SetValue(parser, flagsValue & ~0x1000000);
            }
        }
    }
    uri = new Uri(url);
    return uri;
}

Replaced my original code:

    Uri innUri = null;
    Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out innUri);

with:

    //Uri innUri = null;
    //Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out innUri);
    Uri innUri = MyUri(url);
Phu Minh Pham
  • 1,025
  • 7
  • 21
  • 38
  • @Nkosi, try with Console App, NET 3.5 Apparently something is changed (fixed?) in the later NET Framework implementations – Ivan Stoev Dec 03 '18 at 10:34
  • @Nkosi Yes, it is. But something in NET 4.5 made this code works :) – Ivan Stoev Dec 03 '18 at 11:00
  • I don't think the code or the version is the problem, but the url itself. It seems that this part is the issue `kr./`, while this works fine `https://valgfrigave.dk/image/cache/catalog/50%20kr/notesbog03_1000x1000px-228x228.jpg`. Apparentlty dotnet cannot handle that dot in the url followed by a `/`. – VDWWD Dec 03 '18 at 11:32
  • @Ivan Stoev From .Net 4.0 and above,there has been some fixes which made it possible for the code to download the image. Created a simple console application with the code in my question and it works with .Net 4.0 and above, but not with 3.5 which is the framework I need to use since Axapta 2009 can't handle .Net 4.0 – Phu Minh Pham Dec 03 '18 at 15:37
  • @PhuMinhPham I was saying exactly the same (although in my tests it starts working in 4.5+), so we are on one and the same page :) – Ivan Stoev Dec 03 '18 at 16:04
  • 1
    Both `WebClient` and `HttpWebRequest` internally use a `Uri`. When using `NET 3.5`, the dot character already gets removed when instantiating a `Uri`, whereas `NET 4.5` leaves it as-is. – pfx Dec 03 '18 at 18:43

1 Answers1

2

Problem

As already suspected in comments, the problem is that part of the URL, namely a dot, disappears. This seems to be a bug in .NET 3.5.

Here a screenshot of a https proxy: without the dot there is a 404 since this part of the URL is missing:

proxy

Solution for .NET 3.5

Since you need to stay on .NET 3.5 you can use this cool workaround from a SO answer: https://stackoverflow.com/a/31559579

In your code add the MyUri method from the link above and change the URI creation like so:

Uri innUri = MyUri(url);

Then the download works!

Result

result

Stephan Schlecht
  • 26,556
  • 1
  • 33
  • 47
  • Added the suggested method to my code and replaced the URI creation and now we're able to download the image from the link. We give you a very big thank you! :D – Phu Minh Pham Dec 04 '18 at 09:29