I am able to upload the files to an API, but I need a small help. Right now I just hard-coded it. But actually, I will be having a PDF and XML files in two different local file storage locations, I need to get the files from that location and needs to upload them to API. Can anyone help me to achieve this?
private void btnsubmit_Click(object sender, EventArgs e)
{
UploadFileAsync(#"D:\test\SBP-1102.pdf");
}
public static async Task UploadFileAsync(string path)
{
HttpClient client = new HttpClient();
// we need to send a request with multipart/form-data
var multiForm = new MultipartFormDataContent();
// add file and directly upload it
FileStream fs = File.OpenRead(path);
multiForm.Add(new StreamContent(fs), "files", Path.GetFileName(path));
// send request to API
var url = "https://spaysaas-dev/api/getOCRDocuments";
var response = await client.PostAsync(url, multiForm);
if(response.IsSuccessStatusCode)
{
MessageBox.Show("Success");
}
else
{
MessageBox.Show(response.ToString());
}
}
This answer is incomplete in that it doesn't actually explain why the file isn't being uploaded, but it might help you diagnose the problem.
The documentation on WebClient.UploadFileAsync says:
The file is sent asynchronously using thread resources that are automatically allocated from the thread pool. To receive notification when the file upload completes, add an event handler to the UploadFileCompleted event.
So you could try handling WebClient.UploadFileCompleted and checking the UploadFileCompletedEventArgs for errors.
private void Upload(string fileName)
{
var client = new WebClient();
client.UploadFileCompleted += Client_UploadFileCompleted;
try
{
var uri = new Uri("https://saas-dev/api/getDocs");
{
client.Headers.Add("fileName", System.IO.Path.GetFileName(fileName));
client.UploadFileAsync(uri, fileName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Client_UploadFileCompleted(object sender, UploadFileCompletedEventArgs e)
{
// Check e.Error for errors
}
I am able to upload the PDF file to an API using multi-part form data
Related
Hello im trying upload file to a link and i tried this:
`private void buttonInput_Click(object sender, EventArgs e)
{
try
{
using (WebClient client = new WebClient())
{
var resStr = client.UploadFile(#"https://anonfiles.com", #"C:\Users\sadettin\desktop\test.txt");
var jObjResult = JObject.Parse(Encoding.UTF8.GetString(resStr));
var linkToFile = jObjResult["link"];
}
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
}`
But Im taking 404 error.
Now i want to send any txt file to my discord webhook address and take sent file's link.
How can i do?
Despite your claims, using the correct end-point and a non-zero bytes file does lead to an uploaded file:
using (WebClient client = new WebClient())
{
var resStr = client.UploadFile(#"https://api.anonfiles.com/upload", #"C:\tmp\test.txt");
var jObjResult = JObject.Parse(Encoding.UTF8.GetString(resStr));
var linkToFile = jObjResult["data"]["file"]["url"]["full"].ToString();
MessageBox.Show(linkToFile);
}
Do note that the JSON structure that is returned is different then you seem to handle. The url is found in an attribute full under this path /data/file/url hence this line in my code example:
var linkToFile = jObjResult["data"]["file"]["url"]["full"];
Here is one of the full urls that the service returned to me with my test file
https://anonfiles.com/nai0Z3S0x5/test_txt
It is 106 bytes in total.
I have downloaded a zip file using this code from a web server:
client.DownloadFileAsync(url, savePath);
Then, in another method, during the same session I try and extract the file with this method:
ZipFile.ExtractToDirectory(zipPath, extractDir);
This throws the error:
System.IO.IOException: 'The process cannot access the file
'C:\ProgramData\ZipFile.zip' because it is being used by another process.'
If I restart the program then unzip the file (without redownloading it) it extracts without any problem.
This doesn't make much sense to me because the Webclient client is located in another method and hence should be destroyed...
There is nothing else accessing that file other than the 2 lines of code provided above.
Is there any way to free the file?
You need to extract the files when the download completed, to do this, you need to use DownloadFileCompleted event of webclient
private void DownloadPackageFromServer(string downloadLink)
{
ClearTempFolder();
var address = new Uri(Constants.BaseUrl + downloadLink);
using (var wc = new WebClient())
{
_downloadLink = downloadLink;
wc.DownloadFileCompleted += Wc_DownloadFileCompleted;
wc.DownloadFileAsync(address, GetLocalFilePath(downloadLink));
wc.Dispose();
}
}
private void Wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
UnZipDownloadedPackage(_downloadLink);
}
private void UnZipDownloadedPackage(string downloadLink)
{
var fileName = GetLocalFilePath(downloadLink);
ZipFile.ExtractToDirectory(fileName, Constants.TemporaryMusicFolderPath);
}
I'm trying to download file (image ) using my bot, but when I download the image ( which is done successfully ) after using getFile, the image I received is very small 1.7 kb while it's bigger than that on my mobile phone
This is an old post. But since there is not a good documentation on how you should download file in telegram bot, for anyone wondering, that's how you should do it(One way of it):
DownloadFile(message.Photo[message.Photo.Length - 1].FileId, #"c:\photo.jpg");
in which:
private static async void DownloadFile(string fileId, string path)
{
try
{
var file = await Bot.GetFileAsync(fileId);
using (var saveImageStream = new FileStream(path, FileMode.Create))
{
await file.FileStream.CopyToAsync(saveImageStream);
}
}
catch (Exception ex)
{
Console.WriteLine("Error downloading: " + ex.Message);
}
}
The message.Photo[message.Photo.Length - 1] is the last element in message.Photo array, which contains the highest quality image data. Obviously you can use DownloadFile to download other kind of files(for example message.Document) as well.
the getFile Method present a JSON object (the 1.7 KB response) that contain the data for accessing your image file.
also note that telegram create an array of image for any image. the first element of this array contain the small thumbnail of your original image and the latest element of the array contain your original image.
var file = await Bot.GetFileAsync(message.Document.FileId);
FileStream fs=new FileStream("Your Destination Path And File Name",FileMode.Create);
await Bot.DownloadFileAsync(file.FilePath, fs);
fs.Close();
fs.Dispose();
I use telegram.bot v14.10.0 but I can't find file.FileStream so I find alternative way to get image from telegram. my way is to use telegram api directly for this case.
var test = _myBot.GetFileAsync(e.Message.Photo[e.Message.Photo.Count() - 1].FileId);
var download_url = #"https://api.telegram.org/file/bot<token>/" + test.Result.FilePath;
using (WebClient client = new WebClient())
{
client.DownloadFile(new Uri(download_url), #"c:\temp\NewCompanyPicure.png");
}
//then do what you want with it
You need use await botClient.DownloadFileAsync(file.FilePath, saveImageStream); instead await file.FileStream.CopyToAsync(saveImageStream);
Your code should look like this:
static async void DownloadFile(ITelegramBotClient botClient, string fileId, string path)
{
try
{
var file = await botClient.GetFileAsync(fileId);
using (var saveImageStream = new FileStream(path, FileMode.Create))
{
await botClient.DownloadFileAsync(file.FilePath, saveImageStream);
}
}
catch (Exception ex)
{
Console.WriteLine("Error downloading: " + ex.Message);
}
}
Telegram.Bot from version 14.2.0 commit in examples: https://github.com/TelegramBots/Telegram.Bot.Examples/commit/ff5a44133ad3b0d3c1e4a8b82edce959d0ee0d0e
I'm using dropnet to upload files to the dropbox. Until then everything is working well, but only for small files on it. The following code I'm using to send:
private void btnEnviar_Click(object sender, EventArgs e)
{
var _client = new DropNetClient("xxxxxxxxxxxxx", "xxxxxxxxxxxxxx", "xxxxxxxxxxxxx", "xxxxxxxxxxxxxxxx");
_client.UseSandbox = true;
string arq = "";
string path = "";
foreach (DataGridViewRow dr in dgvArquivos.Rows)
{
if (dr.Cells[0].Value != null)
{
arq = dr.Cells[3].Value.ToString();
path = "//server/documentos/Scanner_/exames";
try
{
var filebytes = new FileInfo(#path+"/"+arq);
byte[] content = _client.GetFileContentFromFS(filebytes);
var result=_client.UploadFile("/exames",arq,content);
this.lblMsg.Text = result.ToString();
dr.Cells[4].Value = "17/12/2014";
}
catch (Exception ex)
{
this.lblMsg.Text= ex.Message.ToString();
}
}
}
}
How do I send files larger on average than 50mb?
Depending on the actual error you're getting the answer might change. ie, if its out of memory or a HTTP error from the API.
DropNet does have support for chunked uploading of files which you might want to have a look at. Documentation for it is a little lacking at the moment but looking at the source should tell you how to use it. https://github.com/DropNet/DropNet/blob/master/DropNet/Client/Files.Sync.cs#L224
Making a call to StartChunkedUpload to start the upload, call AppendChunkedUpload to append more bytes to the upload then call CommitChunkedUpload to complete the upload. Use this with a streaming read of the file if possible to reduce the memory usage.
I'm having a problem with inclomplete blobs being downloaded from Azure storage. The files that are stored are an images. Almost every file that's downloaded ends up missing several lines on the bottom. I've checked the blobs and they were uploaded correctly.
I'm using the following code for downloading a blob from the Azure service:
private async Task Download(CloudBlobClient client)
{
try
{
_media = await _directory.CreateFileAsync(ResourceName, CreationCollisionOption.FailIfExists);
}
catch (Exception)
{
return;
}
using (var stream = await _media.OpenAsync(FileAccessMode.ReadWrite))
{
var blob = await GetBlob(client);
await blob.DownloadToStreamAsync(stream);
_category.NotifyAzureProgress();
await stream.FlushAsync();
}
}
The method GetBlob() looks like this:
private async Task<CloudBlockBlob> GetBlob(CloudBlobClient client)
{
CloudBlobContainer container = client.GetContainerReference(ContainerName);
await container.CreateIfNotExistsAsync();
var blob = container.GetBlockBlobReference(ResourceName);
return blob;
}
Upload code:
private async Task UploadAsync(CloudBlobClient client)
{
_media = await _directory.GetFileAsync(ResourceName);
using (var stream = await _media.OpenAsync(FileAccessMode.Read))
{
var blob = await GetBlob(client);
await blob.UploadFromStreamAsync(stream);
_category.NotifyAzureProgress();
}
}
Thanks for any help!
Edit: I've realized I've missed out one detail - the downloaded image has correct dimensions, but several lines from the bottom are black - it doesn't has the same pixels as the source image. I've checked the MD5 hashes and while they match, when I download the image through an external app, they don't match when I download them with the code above.
Edit2: after inspecting the properties of CloudBlob and the output stream, I've noticed, that even though the blob gives correct length after download, the stream usually says something a little lower. I've tried downloading throught range, but to no avail
Ok, so I've managed to download the images afterall, by partially using the WinRT Azure library combined with a standard .NET HttpClient.
I used the Azure Lib establish the initial connection and then to get only the Blob reference, because the BlockBlobReference has a method to create Shared Access Signature (and I really didn't want to try to construct it myself). Then I created the HttpClient, made a download URL using the SAS and issued a GET request to the URL, which finally worked and downloaded all the images intact.
I think there might be some weird bug in the official library, since using my download method instead of theirs solved everything.
Code sample:
internal async Task Download(CloudBlobClient client)
{
try
{
_media = await _directory.CreateFileAsync(ResourceName, CreationCollisionOption.FailIfExists);
}
catch (Exception)
{
return;
}
try
{
var blob = await GetBlob(client);
HttpClient httpClient = new HttpClient();
var date = DateTime.UtcNow;
var policy = new SharedAccessBlobPolicy();
policy.Permissions = SharedAccessBlobPermissions.Read;
policy.SharedAccessStartTime = new DateTimeOffset(date);
policy.SharedAccessExpiryTime = new DateTimeOffset(date.AddDays(1));
var signature = blob.GetSharedAccessSignature(policy);
var uriString = string.Format("{0}{1}", blob.Uri.ToString(), signature);
var data = await httpClient.GetByteArrayAsync(uriString);
var buf = new Windows.Storage.Streams.Buffer((uint)data.Length);
await FileIO.WriteBytesAsync(_media, data);
_category.NotifyAzureProgress();
}
catch (Exception e)
{
_media.DeleteAsync();
throw e;
}
}