Florin M.
Florin M.

Reputation: 2169

get downloaded file from URL and Illegal characters in path

  string uri = "https://sometest.com/l/admin/ical.html?t=TD61C7NibbV0m5bnDqYC_q";

  string filePath = "D:\\Data\\Name";

  WebClient webClient = new WebClient();
  webClient.DownloadFile(uri, (filePath + "/" + uri.Substring(uri.LastIndexOf('/'))));

/// filePath + "/" + uri.Substring(uri.LastIndexOf('/')) = "D:\\Data\\Name//ical.html?t=TD61C7NibbV0m5bnDqYC_q"

Accesing the entire ( string ) uri, a .ical file will be automatically downloaded... The file name is room113558101.ics ( not that this will help ).

How can I get the file correctly?

Upvotes: 1

Views: 1362

Answers (1)

Evk
Evk

Reputation: 101463

You are building your filepath in a wrong way, which results in invalid file name (ical.html?t=TD61C7NibbV0m5bnDqYC_q). Instead, use Uri.Segments property and use last path segment (which will be ical.html in this case. Also, don't combine file paths by hand - use Path.Combine:

var uri = new Uri("https://sometest.com/l/admin/ical.html?t=TD61C7NibbV0m5bnDqYC_q");
var lastSegment = uri.Segments[uri.Segments.Length - 1];
string directory = "D:\\Data\\Name";
string filePath = Path.Combine(directory, lastSegment);
WebClient webClient = new WebClient();
webClient.DownloadFile(uri, filePath);

To answer your edited question about getting correct filename. In this case you don't know correct filename until you make a request to server and get a response. Filename will be contained in response Content-Disposition header. So you should do it like this:

var uri = new Uri("https://sometest.com/l/admin/ical.html?t=TD61C7NibbV0m5bnDqYC_q");
string directory = "D:\\Data\\Name";
WebClient webClient = new WebClient();  
// make a request to server with `OpenRead`. This will fetch response headers but will not read whole response into memory          
using (var stream = webClient.OpenRead(uri)) {
    // get and parse Content-Disposition header if any
    var cdRaw = webClient.ResponseHeaders["Content-Disposition"];
    string filePath;
    if (!String.IsNullOrWhiteSpace(cdRaw)) {
        filePath = Path.Combine(directory, new System.Net.Mime.ContentDisposition(cdRaw).FileName);
    }
    else {
        // if no such header - fallback to previous way
        filePath = Path.Combine(directory, uri.Segments[uri.Segments.Length - 1]);
    }
    // copy response stream to target file
    using (var fs = File.Create(filePath)) {
        stream.CopyTo(fs);
    }
}

Upvotes: 3

Related Questions