I am trying to create my own download manger.
When a link is added to the download manger I use a webclient to get it's information from the server. Like so
WebClient webClient = new WebClient();
webClient.OpenRead(link);
string filename = webClient.ResponseHeaders["Content-Disposition"];
After that I download the file using DownloadFile
FileInfo fileInfo = new FileInfo(path);
if (!fileInfo.Exists)
{
webClient.DownloadFile(link, path);
}
When I do it like this. I get a WebException timeout.
However, when I remove the webClient.ResponseHeaders part. It never get the timeout exception.
I really need to read the Content-Disposition because some of the links don't have the name of the file on them.
I even tried using a different webclient for downloading and getting it's info but I got the same result.
I was able to fix the problem by finding another way to get the files info.
string Name = "";
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(Link);
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
for(int i=0; i < myHttpWebResponse.Headers.Count; i++)
{
if (myHttpWebResponse.Headers.Keys[i] == "Content-Disposition")
{
Name = myHttpWebResponse.Headers[i];
}
}
myHttpWebResponse.Close();
Related
I want to get a link from a TextBox and download a file from link.
But before downloading file, I want to know the size of the file in advance and create an empty file with that size. but I can't.
and another question, I want to show percentage of download progress. How can I know data is downloaded and I should update the percentage?
WebRequest request = WebRequest.Create(URL);
WebResponse response = request.GetResponse();
totalSize = request.ContentLength;//always is -1
using (FileStream f = new FileStream(savePath, FileMode.Create))
{
f.SetLength(totalSize);
}
System.IO.StreamReader reader = new
System.IO.StreamReader(response.GetResponseStream());
WebClient client = new WebClient();
client.DownloadFile (URL, savePath);
The best way would be to use the WebClient with its DownloadFile Function, which has an async callback for events like Completed or ProgressChanged.
Getting the size of the file in advance would be a step harder though.
Im trying to create a web service which gets to a URL e.g. www.domain.co.uk/prices.csv and then reads the csv file. Is this possible and how? Ideally without downloading the csv file?
You could use:
public string GetCSV(string url)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string results = sr.ReadToEnd();
sr.Close();
return results;
}
And then to split it:
public static void SplitCSV()
{
List<string> splitted = new List<string>();
string fileList = getCSV("http://www.google.com");
string[] tempStr;
tempStr = fileList.Split(',');
foreach (string item in tempStr)
{
if (!string.IsNullOrWhiteSpace(item))
{
splitted.Add(item);
}
}
}
Though there are plenty of CSV parsers out there and i would advise against rolling your own. FileHelpers is a good one.
// Download the file to a specified path. Using the WebClient class we can download
// files directly from a provided url, like in this case.
System.Net.WebClient client = new WebClient();
client.DownloadFile(url, csvPath);
Where the url is your site with the csv file and the csvPath is where you want the actual file to go.
In your Web Service you could use the WebClient class to download the file, something like this ( I have not put any exception handling, not any using or Close/Dispose calls, just wanted to give the idea you can use and refine/improve... )
using System.Net;
WebClient webClient = new WebClient();
webClient.DownloadFile("http://www.domain.co.uk/prices.csv");
then you can do anything you like with it once the file content is available in the execution flow of your service.
if you have to return it to the client as return value of the web service call you can either return a DataSet or any other data structure you prefer.
Sebastien Lorion's CSV Reader has a constructor that takes a Stream.
If you decided to use this, your example would become:
void GetCSVFromRemoteUrl(string url)
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (CsvReader csvReader = new CsvReader(response.GetResponseStream(), true))
{
int fieldCount = csvReader.FieldCount;
string[] headers = csvReader.GetFieldHeaders();
while (csvReader.ReadNextRecord())
{
//Do work with CSV file data here
}
}
}
The ever popular FileHelpers also allows you to read directly from a stream.
The documentation for WebRequest has an example that uses streams. Using a stream allows you to parse the document without storing it all in memory
I've been looking at file transfer tutorials for windows phone 8, but for some reason they all seem quite code extensive for what i want, wich is simply to download a file(image in this case) to the phone and use the path its been saved too as a source of a control
i get the following Json from a webservice
[{"name":"image1.png","link":"http://www.xxxxxx.com/image1.png"},{"name":"image2.png","link":"http://www.xxxxxx.com/image1.jpg"}]
and want to use those links to do the downloads
in sum i want to
Check if file exists, if not download, and get its path to use later.
First you need to parse the JSON, I would recommend Newtonsoft JSON for that.
After that you need to check if file exists. (You could use the MD5 of the URL as the filename for localstorage and check if there is a file with the name)
If the file does not exist you need to use a HttpWebRequest to download the file and then save it to the isolated storage.
EDIT:
To check if file exists:
IsolatedStorageFile localStorage = IsolatedStorageFile.GetUserStoreForApplication();
if(localStorage.FileExists("image1.png"))
//use cached version
WebRequest:
WebRequest req = HttpWebRequest.Create("http://domain.com/image.png");
WebResponse res = await GetResponseAsync(req);
if (res != null)
{
Stream rspStream = res.GetResponseStream();
//save stream to isolated storage
}
GetResponseAsync:
private static Task<HttpWebResponse> GetResponseAsync(WebRequest request)
{
var taskComplete = new TaskCompletionSource<HttpWebResponse>();
request.BeginGetResponse(asyncResponse =>
{
try
{
HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
HttpWebResponse someResponse = (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
taskComplete.TrySetResult(someResponse);
}
catch (WebException webExc)
{
HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
taskComplete.TrySetResult(failedResponse);
}
}, request);
return taskComplete.Task;
}
I get this strange error suddenly saying System.Net.WebException : The request was abborted: The Request was canceled. ---> System.NotSupportedException : This method is not supported by this class . I dont know why is occurring cause it used to work fine.
I tried searching online but found no help on this matter. the follwing is the method that that i am having pronlems with and i have pointed out the line that gives out the error.
//get column heading names from formatted text file
public string getFTextColumnHead(string serverURL, string userName, string password, int headRow,
string filePath, string reqFrom)
{
string line = "";
//initialize WebClient object
WebClient client = new WebClient();
//if the request is for web
if (reqFrom == "web")
{
//send web request to retreive the data from the url
HttpWebRequest req = (HttpWebRequest) WebRequest.Create(serverURL);
//parse credentials to the web server to authenticate
client.Credentials = new NetworkCredential(userName, password);
//Grab Data from the web server and save to the given path
client.DownloadFile(new Uri(serverURL), filePath);//<---exception occurs here
}
//initialize input output stream and open the downloaded file
StreamReader file = new StreamReader(filePath);
//loop through the rows of the file until the column heading row is reached
for (int i = 0; i < headRow; i++)
{
//read the line
line = file.ReadLine();
}
//dipoase the client
client.Dispose();
//return the column heading string
return line;
}
Thank you guys. I am closing in my deadline for this project. all this happened right in the last moment. help is very much appreciated :)
P.S. I installed Resharper to review the code. but i did not make any changes it suggested to this particular class :).
In my application I use the WebClient class to download files from a Webserver by simply calling the DownloadFile method. Now I need to check whether a certain file exists prior to downloading it (or in case I just want to make sure that it exists). I've got two questions with that:
What is the best way to check whether a file exists on a server without transfering to much data across the wire? (It's quite a huge number of files I need to check)
Is there a way to get the size of a given remote file without downloading it?
Thanks in advance!
WebClient is fairly limited; if you switch to using WebRequest, then you gain the ability to send an HTTP HEAD request. When you issue the request, you should either get an error (if the file is missing), or a WebResponse with a valid ContentLength property.
Edit: Example code:
WebRequest request = WebRequest.Create(new Uri("http://www.example.com/"));
request.Method = "HEAD";
using(WebResponse response = request.GetResponse()) {
Console.WriteLine("{0} {1}", response.ContentLength, response.ContentType);
}
When you request file using the WebClient Class, the 404 Error (File Not Found) will lead to an exception. Best way is to handle that exception and use a flag which can be set to see if the file exists or not.
The example code goes as follows:
System.Net.HttpWebRequest request = null;
System.Net.HttpWebResponse response = null;
request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create("www.example.com/somepath");
request.Timeout = 30000;
try
{
response = (System.Net.HttpWebResponse)request.GetResponse();
flag = 1;
}
catch
{
flag = -1;
}
if (flag==1)
{
Console.WriteLine("File Found!!!");
}
else
{
Console.WriteLine("File Not Found!!!");
}
You can put your code in respective if blocks.
Hope it helps!
What is the best way to check whether a file exists on a server
without transfering to much data across the wire?
You can test with WebClient.OpenRead to open the file stream without reading all the file bytes:
using (var client = new WebClient())
{
Stream stream = client.OpenRead(url);
// ^ throws System.Net.WebException: 'Could not find file...' if file is not present
stream.Close();
}
This will indicate if the file exists at the remote location or not.
To fully read the file stream, you would do:
using (var client = new WebClient())
{
Stream stream = client.OpenRead(url);
StreamReader sr = new StreamReader(stream);
Console.WriteLine(sr.ReadToEnd());
stream.Close();
}
In case anyone stuck with ssl certificate issue
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback
(
delegate { return true; }
);
WebRequest request = WebRequest.Create(new Uri("http://.com/flower.zip"));
request.Method = "HEAD";
using (WebResponse response = request.GetResponse())
{
Console.WriteLine("{0} {1}", response.ContentLength, response.ContentType);
}