Search code examples
c#system.io.file

webClient.DownloadData throw 'System.IO.PathTooLongException'


I have an method which is download images via URL and sometimes URL become like this, which contains very long path (i removed some string,it just didnt beacome long question :) :

data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxITEhUSEBAVFhMXGRcXFRgWFRcVGRcYFhcXFhUVGBgYISggGBslGxgaITEhJSkrLi8uGCAzODMsNygtLisBCgoKDg0OFxAQGysfHSUtLS8tLS0tLS0tLSstLS0wLS4tLS0tLS0tLS0tKystNy0uLy0rKy0tLS0rNS0tLS0tLf/AABEIALoBDwMBIgACEQEDEQH/xAAcAAEAAgIDAQAAAAAAAAAAAAAABAUCBgEDBwj/xABLEAABAwMCAgYDCgsHAwUAAAABAAIDBBESBSExQQYTFCJRYXGBkQcjMkJTVJOh0fAVJDNSYpKUscHS4RYXQ1VjcoKEorJEg6TCw//EABkBAQEBAQEBAAAAAAAAAAAAAAABAgMEBf/EACURAQEAAgIABQQDAAAAAAAAAAABAhEDIQQSMWFxQYGh0QUTUf/aAAwDAQACEQMRAD8A9xREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQERaH0h90yGnnfAyB8hYcXnIMGQ4gbG/p2Qb4i8p1v3S5JYsKZjoJLtOd2v2B7zcS224Vezp9WBtjISfGzRf1Yq6Tb2ZF4vN7o1WxhJJNud2j6sFd9HPdJc98UUrLukIsTxsSG/FAHHyTRt6aiIooiIgIiICIiAiIgIiICIiAiIgIiICLQPdM6eu09zIomgyOAeSd7NJc22J8S3jflwWtRe6lOWA2Nz+ixWQ29kReR/wB5suNrSZ+OMdvYrLT/AHVImsAnhmc/mWiMA/8AcP3Jqm3pSLU+jPT6mrJepY2SN5BLRIG96wuQC0ncAX3W2KAiIgIiIC+Zdbqc6uodfjNKfV1hsvpeeQNaXHgASfULr5WgeS5zjxO59JN1YlV2txh1S+9+DedvihRuzDll+sV36i78Yf8A8f8AxauHnYrUgvNa6MGmfKXOqXxRmMZX6okv3dfLLhwsAd3i9sSDC0mgZO4hjp2hjDI976lrGNawxhzr9X+c4gDxezwJPoPS8Na2okfA17Gy0Tne9NbsDGHMBLiRk1rmk+TmnjYU/Seth1LrYaGJ8kgpy8PdHHE4lk0TnRNYxoLhgBxN+4OO6zbpdKJjbgW1GUE346jHsQDx8r2+tZNikc5rY9Qnc5xxaG1zXnibEhlzb4PAcneVuqHR6kNv2V4cRnbstmhx7mHwdm4d7h8McPjKVQ6HKZYwYJQ0PYS50JjIZEQWuyHxyC644ktbudrZVArqqWJ5Y6rrDaxDm1Jc1zXAOa5p2uC0+A34gWIXXBqErnNa2qri5xa0ATm7nOLQAN+JJcB/x81ues6tRR0r6eeEds6ppwELXWlkizDnTD4OJcBYEEY8CFpPRvTTUztiLywWfI5zW5ODYmOkd1bR8J/dsB4lal63UqZqT6mnf1dRUV8cmIdi6e5s6+JNn7bj2KFJq7x/6yu5/wCMf0rX7/8As/7vJTtboGOpoq6CeeSJ73QWqQOtY6MF1g4Eh7LHa3C9uRVl0a1bTYqGojrIgZiXFvvHWueMW9W1ribMs4OJ4cRv4tzXSR3w9G68sa91ZVR5Nza2SoIfgT3SWh5xuOF7IejFf/mMvK/4y/8ARvxeP0/Y3xNrbpTptdN1U0MdTIHRtPvdzjtvcRkcrAHyB5Kh/A+pgginrfU2Yf8A22F7gLkdTe3GXA6pYdW1+boW2uSQY+HEWHO/eGwFyOuXVIopDBT0TJWxho6yXKR0pc3IOFm37wu4AkbA7AbLlusnb8Tp7DicHgG++RIbwDO/tbu778F6cPBc3JjMscer8JeTGdWq3WqWoe4NfWCYC+5aWAOyc3bEHIWFAiIgIiICIiD/2Q==

And then when i debug or when its come to download image, i get this Exception:

var DL = webClient.DownloadData(base64)
The specified path and / or file name is too long. The fully qualified name must be less than 260 characters and the folder name must be less than 248 characters.

i did also research which is suggested to add <httpRuntime maxUrlLength="260" /> in webconfig or used different library , but unfortunately it didnt help to solve the problem.
Can anyone please help me or point me into the right direction :)
Thanks in advance.

Controller:

[HttpPost]
public string DownloadImagesFromLinkViaURL(ImagesViewModel model)
{
 var RandomName = Guid.NewGuid().ToString("N").Substring(0,12);
    using (WebClient webClient = new WebClient())
    {
        try
        {
            string base64 = model.ImageURL.Substring(model.ImageURL.IndexOf(',') + 1);
            byte[] data = Convert.FromBase64String(base64);
            var DL = webClient.DownloadData(base64);

            using (MemoryStream mem = new MemoryStream(DL))
            {
                using (var content = Image.FromStream(mem))
                {
                    var format = ImageFormat.Png.ToString().ToLower();

                    var PathIMG = "https://SomeName.com/folder/" + RandomName + "." + format;

                    content.Save(Path.Combine(Server.MapPath(PathIMG)));
                    ImageStore img = new ImageStore();

                    img.ProducentVarenr = model.ImageName;
                    img.ImageOrginalURL = model.ImageURL;
                    img.ImageRandomName = RandomName;
                    img.LinktilBillede = PathIMG;
                    db.ImageStoreList.Add(img);
                    db.SaveChanges();
                }
            }

        }
        catch (ArgumentException)
        {
            return "content is not image";
        }

    }
    return "saved";
}

ViewModal:

public class ImagesViewModel
{
    public int ImageID { get; set; }
    public string ImageURL { get; set; }
    public string ImageName { get; set; }
    public string ImagePath { get; set; }
    public string RandomName { get; set; }
}

Solution

  • Data you see is not url or path. It is image data presented as Base64 string. So no any downloading is needed since you have image data already.

    If you paste that very long string i.e this base64-to-image converter tool, you see actual image.

    With given base64-string you can save it to file with following style:

    File.WriteAllBytes(@"c:\yourfile", Convert.FromBase64String(base64));
    

    Here is (non-tested and non-refactored) fixed version of your original method, as requested in answer comments.

    [HttpPost]
    public string DownloadImagesFromLinkViaURL(ImagesViewModel model)
    {
        var RandomName = Guid.NewGuid().ToString("N").Substring(0, 12);
        var format = ImageFormat.Png.ToString().ToLower();
    
        var PathIMG = "https://SomeName.com/folder/" + RandomName + "." + format;
        if (model.ImageURL.StartsWith("data:image"))
        {
            string base64 = model.ImageURL.Substring(model.ImageURL.IndexOf(',') + 1);
            File.WriteAllBytes($@"c:\temp\{RandomName}.jpeg", Convert.FromBase64String(base64));
            ImageStore img = new ImageStore();
    
            img.ProducentVarenr = model.ImageName;
            img.ImageOrginalURL = model.ImageURL;
            img.ImageRandomName = RandomName;
            img.LinktilBillede = PathIMG;
            db.ImageStoreList.Add(img);
            db.SaveChanges();
            return "saved";
        }
        using (WebClient webClient = new WebClient())
        {
            try
            {
                byte[] data = Convert.FromBase64String(base64);
                var DL = webClient.DownloadData(base64);
    
                using (MemoryStream mem = new MemoryStream(DL))
                {
                    using (var content = Image.FromStream(mem))
                    {
                        content.Save(Path.Combine(Server.MapPath(PathIMG)));
                        ImageStore img = new ImageStore();
    
                        img.ProducentVarenr = model.ImageName;
                        img.ImageOrginalURL = model.ImageURL;
                        img.ImageRandomName = RandomName;
                        img.LinktilBillede = PathIMG;
                        db.ImageStoreList.Add(img);
                        db.SaveChanges();
                    }
                }
    
            }
            catch (ArgumentException)
            {
                return "content is not image";
            }
    
        }
        return "saved";
    }