I get wrong file when I download it by C# code - c#

When I open this excel file link in my browser, It will be downloaded successfully.
But when I download it by the following c# code
private void downloadFile()
{
string remoteUri = "http://members.tsetmc.com/tsev2/excel/MarketWatchPlus.aspx?d=0";
string fileName = #"g:\temp.xlsx";
using (var client = new WebClient())
{
client.DownloadFile(remoteUri, fileName);
}
}
and I open it in the file explorer, I get the file format error:
What is wrong with my code?

Unzip file and write.
string remoteUri = "http://members.tsetmc.com/tsev2/excel/MarketWatchPlus.aspx?d=0";
string fileName = #"g:\temp.xlsx";
using (var client = new WebClient())
{
using var stream = client.OpenRead(remoteUri);
using var zipStream = new GZipStream(stream, CompressionMode.Decompress);
using var resultStream = new MemoryStream();
zipStream.CopyTo(resultStream);
File.WriteAllBytes(fileName, resultStream.ToArray());
}

If you look at the response headers provided by the remoteUri, you will notice that the particular endpoint is actually serving content in compressed format.
Content-Encoding: gzip
So the content you get back is not a direct excel file, rather a zip file. So for the piece of code to work, the file name should be temp.zip instead of temp.xlsx
private void downloadFile()
{
string remoteUri = "http://members.tsetmc.com/tsev2/excel/MarketWatchPlus.aspx?d=0";
string fileName = #"g:\temp.zip";
using (var client = new WebClient())
{
client.DownloadFile(remoteUri, fileName);
}
}
Having said that, inline is a better approach to download the file.
Create an instance of HttpClient by passing in a HttpClientHandler which has the AutomaticDecompression property set to DecompressionMethods.GZip to handle Gzip decompression automatically. Next read the data and save it to temp.xlsx file.
string remoteUri = "http://members.tsetmc.com/tsev2/excel/MarketWatchPlus.aspx?d=0";
string fileName = #"g:\temp.xlsx";
HttpClientHandler handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
HttpClient client = new HttpClient(handler);
var response = await client.GetAsync(remoteUri);
var fileContent = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes(fileName, fileContent);

Related

Downloading a file from the website via the download link

There's a code that downloads files by links (.exe), which actually needs a link to download the file, it can be a direct link or a link to the file that needs to be downloaded. In 80% of cases, everything works (https://ru.download.nvidia.com/GFE/GFEClient/3.25.1.27/GeForce_Experience_v3.25.1.27.exe (https://www.nvidia.com/en-gb/geforce/geforce-experience/)), but where you need to confirm the cookie (https://drivers.amd.com/drivers/installer/22.20/beta/amd-software-adrenalin-edition-22.8.2-minimalsetup-220825_web.exe (https://www.amd.com/en/support)), the download doesn't work
Maybe it can somehow work normally?
using var handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.CookieContainer = new CookieContainer();
handler.UseCookies = true;
using var client = new HttpClient(handler);
SaveFile(client, fileUri, destinationFolder)
async Task SaveFile(HttpClient client, Uri uri, string destinationFolder)
{
using var response = await client.GetAsync(uri);
using var stream = await response.Content.ReadAsStreamAsync();
var name = Guid.NewGuid().ToString() + ".exe";
using var fs = new FileStream(Path.Combine(destinationFolder, name), FileMode.CreateNew);
await stream.CopyToAsync(fs);
}

How to Solve Azure DataLakeStore File Content-Disposition Added in file?

I was Uploaded Text file or image file or Zip File to Azure Data Lake Store. it' was Uploaded Successfully. But, before added some content in file.
I was Uploaded a File using Rest API. (Uploaded file using HttpClient in C#)
this Type of Content Added in
---b8b2dfc6-6128-43b5-8fb8-022820aedf02
Content-Disposition: form-data;
name=file1; filename=tick.txt; filename*=utf-8''tick.txt
If the Content Added So, The Image file and zip files are Not Open in Viewer/Explore.
How To Remove this type of header added in file From Upload.Here I shared my file uploaded code.
public object UploadFile(string srcfile, string destFilePath, bool force = true)
{
var uploadurl = string.Format(UploadUrl, _datalakeAccountName, destFilePath);
var stream = File.OpenRead(srcfile);
HttpContent fileStreamContent = new StreamContent(stream);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accesstoken.access_token);
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileStreamContent, "file1", Path.GetFileName(srcfile));
var response = client.PutAsync(uploadurl, formData).Result;
return new { Status = response.StatusCode, Message = response.ReasonPhrase, details = response.ToString() };
}
}
}
Thanks in Advance.
Please have try to use the following code, it works correcly on my side.
public object UploadFile(string srcfile, string destFilePath, bool force = true)
{
var uploadurl = string.Format(UploadUrl, _datalakeAccountName, destFilePath);
var stream = File.OpenRead(srcfile);
HttpContent fileStreamContent = new StreamContent(stream);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new
AuthenticationHeaderValue("Bearer", _accesstoken.access_token);
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/octet-stream"));
var response = client.PutAsync(uploadurl, fileStreamContent).Result;
return new { Status = response.StatusCode, Message = response.ReasonPhrase, details = response.ToString() };
}
}

Any one knows how to upload file from ASP.net to remote rest service ( not WCF)

I need to implement upload method in ASP.net c# to upload file to remote rest service instead uploading it to my local machine.
I have wrote a function that posts data to the rest service now I want to know how to post the file stream to the rest service ?
I am using the following lines of code to post the data
if (!string.IsNullOrEmpty(PostData) && Method == HttpVerb.POST)
{
var encoding = new UTF8Encoding();
var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(PostData);
request.ContentLength = bytes.Length;
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
know how to make postData is my file stream ? instead of string.
In the past I have use this technique:
private static StreamContent CreateFileContent(Stream fileStream, string fileName, string contentType)
{
var fileContent = new StreamContent(fileStream);
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"files\"",
FileName = "\"" + fileName + "\""
}; // the extra quotes are key here
fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
return fileContent;
}
And then an upload via a HttpClient like this:
private async Task UploadFile(HttpClient client, Stream fileStream, string filename)
{
//HttpClient initialized by caller
using (var content = new MultipartFormDataContent())
{
//file contains XML
content.Add(CreateFileContent(fileStream, filename, "text/xml"));
var resp = await client.PostAsync("the/rest/endpoint", content);
resp.EnsureSuccessStatusCode();
}
return;
// Error handling left as an exercise for the reader.
}

Send file to service using Microsoft.Net.Http

I have a method:
private bool UploadFile(Stream fileStream, string fileName)
{
HttpContent fileStreamContent = new StreamContent(fileStream);
using (var client = new HttpClient())
{
using (var formData = new MultipartFormDataContent())
{
formData.Add(fileStreamContent, fileName, fileName);
var response = client.PostAsync("url", formData).Result;
return response.StatusCode == HttpStatusCode.OK;
}
}
}
}
That is sending the file to a WCF service, but looking at the Wireshark log of the post, the fileStream isn't being appended, just the filename. Do I need to do something else?
Use a ByteArrayContent instead of a stream content.
var fileContent = new ByteArrayContent(File.ReadAllBytes(fileName));
Then specify your content disposition header:
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
formData.Add(fileContent);
Turns out the fileStream wasn't getting to the method. Using context.Request.Files[0].InputStream seemed to be the culprite. Using .SaveAs and then reading it in as a byteArray and attaching that to the MultiPartFormDataContent worked.

How do I download zip file in C#?

I use HTTP GET that downloads a zip file in a browser, something like https://example.com/up/DBID/a/rRID/eFID/vVID (not the exact url)
Now, when I try to do the same download in C# code(same GET method as above) for a desktop application, the zip file downloaded is not a valid archive file. When I opened this file in notepad, it was some HTML page.
I think I'm not setting some header correctly. I looked around for examples. I'd found several wrt uploads, but did not see anything for downloads.
Code:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/zip";
try
{
HttpWebResponse res = (HttpWebResponse)request.GetResponse();
using (StreamReader sr = new StreamReader(res.GetResponseStream(), System.Text.Encoding.Default))
{
StreamWriter oWriter = new StreamWriter(#"D:\Downloads\1.zip");
oWriter.Write(sr.ReadToEnd());
oWriter.Close();
}
res.Close();
}
catch (Exception ex)
{
}
It's mainly because you use a StreamWriter : TextWriter to handle a binary Zip file. A StreamWriter expects text and will apply an Encoding. And even the simple ASCII Encoder might try to 'fix' what it thinks are invalid line-endings.
You can replace all your code with:
using (var client = new WebClient())
{
client.DownloadFile("http://something", #"D:\Downloads\1.zip");
}
Note that for new code you should look at HttpClient instead of WebClient.
And then don't use using( ) { }
You could just use WebClient for a 2-liner:
using(WebClient wc = new WebClient())
{
wc.DownloadFile(url, #"D:\Downloads\1.zip");
}
You can also use System.Net.Http.HttpClient
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(downloadURL))
{
using(var stream = await response.Content.ReadAsStreamAsync())
{
using(Stream zip = FileManager.OpenWrite(ZIP_PATH))
{
stream.CopyTo(zip);
}
}
}
}
Expanding on Ruben's answer which uses HttpClient instead of WebClient, you can add as an extension method like this:
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
public static class Extensions
{
public static async Task DownloadFile (this HttpClient client, string address, string fileName) {
using (var response = await client.GetAsync(address))
using (var stream = await response.Content.ReadAsStreamAsync())
using (var file = File.OpenWrite(fileName)) {
stream.CopyTo(file);
}
}
}
And then use like this:
var archivePath = "https://api.github.com/repos/microsoft/winget-pkgs/zipball/";
using (var httpClient = new HttpClient())
{
await httpClient.DownloadFile(archivePath, "./repo.zip");
}

Categories

Resources