I am calling API
https://do.convertapi.com/Pdf2PowerPoint
Their website for the API details is
https://www.convertapi.com/
To upload the file in their C# documentation they have used client.UploadFile() function which expects file name parameter from physical location. in my case i have bytes of PDF file coming on the fly without storing that to physical location and I want to upload that bytes instead. I am using client.UploadData() function which expects byte array and I have provide that. but their API is throwing error and is asking to provide File name which is must.
I think Developers of API would only be able to answer. But if you guys have any idea if I am doing any mistake to upload file. please suggest your workaround.
Please find my code below as requested
var client = new WebClient();
var data = new NameValueCollection();
data.Add("OutputFileName", "TestOutput.pptx"); //Optional
data.Add("File", "Revised.pdf");
data.Add("ApiKey", "484700111"); //API Key must be set if you purchased membership with credits. Please login to your control panel to find out your API Key http://www.convertapi.com/prices
try
{
client.QueryString.Add(data);
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
//I am using ReadAllBytes Approach for now as in my practical scenario I am going to get bytes instead of sending file from Physical location
byte[] Arr = File.ReadAllBytes(#"D:\PPTTest\Level I and II Revised.pdf");
// Error here : File Parameter can not be null
var response = client.UploadData("https://do.convertapi.com/Pdf2PowerPoint", Arr);
var responseHeaders = client.ResponseHeaders;
var path = Path.Combine(#"D:\PPTTest\", responseHeaders["OutputFileName"]);
File.WriteAllBytes(path, response);
//Console.WriteLine("The conversion was successful! The word file {0} converted to PDF and saved at {1}", fileToConvert, path);
}
catch (WebException e)
{
Console.WriteLine("Exception Message :" + e.Message);
if (e.Status == WebExceptionStatus.ProtocolError)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
}
}
Thanks,
Hira
Code taken from this post. You have to upload file with multipart/form-data request like this:
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new StringContent(username), "username");
form.Add(new StringContent(useremail), "email");
form.Add(new StringContent(password), "password");
form.Add(new ByteArrayContent(imagebytearraystring, 0, imagebytearraystring.Count()), "profile_pic", "hello1.jpg");
HttpResponseMessage response = await httpClient.PostAsync("PostUrl", form);
Related
I'm trying to download REST API response content as (original format) excel (.xlsx)
My request url is :- https://www.connect2nse.com/extranet-api/member/file/download/1.0?segment=CM&folderPath=/Reports&filename=07141_AR1_Dec22.xlsx
And I'm downloading the 07141_AR1_Dec22.xlsx file.
So, I have used this method to return the response content
public static string DownloadFileName()
{
try
{
var client = new RestClient("https://www.connect2nse.com/extranet-api/member/file/download/1.0?segment=CM&folderPath=/Reports&filename=07141_AR1_Dec22.xlsx");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer eyJhbGciOweSUzI1NiJ9.eyJtZW1iZXJDZCI6IjA3MTQxIiwic3ViIjoiMDcxNDEiLCJsb2dpbklkIjoiYm5yaG8xIiwiaXNzIjoiYm5yaG8xIiwiZXhwIjoxNjc0ODA0NDE0LCJpYXQiOjE2NzQ4MDA4MTQsImp0aSI6ImEwY2U3NjNkLWY1OWUtNDY2Yy1hMmMwLTUwNGQwZDgzOTQwYiJ9.UCnkkvTTi9fZjWWak5deXgxPEqMG16FQP4Cy_u1cR0hQb-xQ4LAhbfpMtFz1WXQ4fz7ZmRhkR1i9JXY4w32lzQ");
request.AddHeader("Cookie", "HttpOnly");
var body = #"";
request.AddParameter("text/plain", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
//Console.WriteLine(response.Content);
return response.Content;
}
catch (Exception)
{
throw;
}
}
And I'm calling this method in btnDownload_Click event in windows forms application
private void btnDownload_Click(object sender, EventArgs e)
{
string downloadfile = DownloadFileName();
string _tradelogfile = Application.StartupPath + "\\07141_AR1_Dec22.xlsx";
using (System.IO.StreamWriter file = new System.IO.StreamWriter(_tradelogfile, true))
{
file.WriteLine(downloadfile);
}
}
The DownloadFileName method is returning the output like below image
So if I keep execute the program the file is downloading at specified location
Like below example
While I'm opening the file it is throwing warning errors and file is not opening like below
In the postman response also I'm getting the response like below image
And I have read this article for better understanding but it not helped to me.
Please suggest me where I did the mistake and how to save(download) this REST API response content as excel format(.xlsx).
Should I use any dll or is my code issue ?
Please suggest.
I've been trying to get uploading an image anonymously onto Imgur using the Imgur API to work, however I've been facing an issue with unauthorized path access.
I've tried search around other similar articles on Microsoft Docs and posts here on stack overflow but couldn't find a solution. I've even given my application "broadFileSystemAccess" as rescap capability in my Package.appxmanifest which I found from reading the Microsoft UWP documentations.
The error I receive is:
System.UnauthorizedAccessException: 'Access to the path 'C:\Users\lysyr\Pictures\ROG Logo.png' is denied.'
The error occurs at the var filecon = File.ReadAllBytes(imgpath); line.
My File Picker code is:
public static string imgpath = "";
public static string finalimg = "";
private async void FileNameButton_Click(object sender, RoutedEventArgs e)
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
// Application now has read/write access to the picked file
imgpath = file.Path;
var filecon = File.ReadAllBytes(imgpath); #Error drops here <---
finalimg = Convert.ToBase64String(filecon);
await ImgurUploadAPI();
Debug.WriteLine("Picked Image: " + file.Name);
uploadedimage_text.Text = "Picked Image: " + file.Name;
}
else
{
Debug.WriteLine("Image uploading has been cancelled.");
}
}
And the ImgurUpload task code is:
public static string imgurlink = "";
public async Task ImgurUploadAPI()
{
try
{
if (imgpath != null)
{
// Construct the HttpClient and Uri
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("https://api.imgur.com/3/upload");
httpClient.DefaultRequestHeaders.Add("Authorization", "Client-ID IMGUR-CLIENTIDHERE");
//Debug.WriteLine("Request Headers: ");
// Construct the JSON to post
HttpStringContent content = new HttpStringContent("image=\"{finalimg}\"");
Debug.WriteLine("Request Upload: " + content);
// Post the JSON and wait for a response
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(
uri,
content);
// Make sure the post succeeded, and write out the response
httpResponseMessage.EnsureSuccessStatusCode();
var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
imgurlink = httpResponseBody;
Debug.WriteLine("Request Response: " + httpResponseBody);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
I feel like it might be something to do with the way I access and convert the image to be ready for upload. Any tips would be very appreciated as I've been stuck on this for awhile now and it's one of the last things I need to complete for my project. Cheers!
Besides #Julian Silden Langlo answer. there is another option for your scenario. The reason for this behavior is that you could not directly access the file using File.ReadAllBytes(String) Method.
I noticed that you've already added the broadFileSystemAccess capability, what you need to note is that this capability only works for the Windows.Storage APIs. So you could only use it like
StorageFile file = StorageFile.GetFileFromPathAsync(filepath)
When you use UWP your access to the file system is limited. This means that you can't simply read a file at an arbitrary path like you're trying to do here:
var filecon = File.ReadAllBytes(imgpath);
What you need to do instead is to ask the StorageFile object you received from the FilePicker for a read Stream. Like so:
var buffer = await FileIO.ReadBufferAsync(file);
var filecon = buffer.ToArray();
finalimg = Convert.ToBase64String(filecon);
You can find more information about file access for UWP at Microsoft Docs.
looking on the web, I saw a little bit how to POST a 'file' and therefore, I wrote my code in this way:
var upfilebytes = File.ReadAllBytes((string)fPath);
//create new HttpClient and MultipartFormDataContent and add our file, and StudentId
HttpClient client = new HttpClient();
MultipartFormDataContent content = new MultipartFormDataContent();
ByteArrayContent baContent = new ByteArrayContent(upfilebytes);
content.Add(baContent, "img", fPath);
StringContent emailText = new StringContent(lbl_email.Text);
content.Add(emailText, "email");
string url = "http://192.168.178.77/TestLoginURL/api/updateUserImage.php";
//upload MultipartFormDataContent content async and store response in response var
var response =
await client.PostAsync(url, content);
//read response result as a string async into json var
var responsestr = response.Content.ReadAsStringAsync().Result;
now the problem is another ... this is my API code:
<?php
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST'){
//getting values
$img = $_FILES['img']['name'];
$email = $_POST['email'];
//including the db operation file
require_once '../includes/DbOperation.php';
$db = new DbOperation();
$target = "/Applications/XAMPP/xamppfiles/htdocs/TestLoginURL/images/".basename($img);
//inserting values
if($db->updateImage((String)basename($img),$email)){
$response['error']=false;
$response['message']='Image added successfully - test fileName = '.(String)basename($img);
}else{
$response['error']=true;
$response['message']='Could not add image';
}
if(move_uploaded_file($_FILES['img']['tmp_name'], $target)) {
/*$response['error']=false;
$response = "Image uploaded successfully";*/
}else{
$response['error']=true;
$response = "Failed to upload image";
}
}else{
$response['error']=true;
$response['message']='You are not authorized';
}
echo json_encode($response);
With Postman it works perfectly, updates the name of the image in the database and physically inserts the image in the designated path and the response message for example is this: {"error": false, "message": "Image added successfully - test fileName = trollolollo.png"}
Now, the app saves the file in the right repository but does NOT UPDATE the name of the 'image' in the database ... BUT strangely, the "response" message in the debugger also correctly shows the name of the FILE ... So I just don't understand where I'm wrong ... Could someone help me with the code please? Thanks
OFF_TOPIC: usually, when I have to send only strings, I send a post request written in this way
string url = "http://192.168.178.77/TestLoginURL/api/insertUser.php";
FormUrlEncodedContent formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("nickname", nickname),
new KeyValuePair<string, string>("password", password1),
new KeyValuePair<string, string>("email", email)
});
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
try
{
CancellationTokenSource cts = new CancellationTokenSource();
var responseMessage = httpClient.PostAsync(url, formContent).Result;
}
catch (Exception ex)
{
ex.Message.ToString();
throw;
}
but now, being a file and having no experience about it I am having difficulties...
thanks again, I hope someone can help me with the code
Are you sure that you are handling update query correctly ?
Update query will only return false on a failure if you messed up the SQL query or anything like that. So you have to use mysqli_stmt_affected_rows to see if a row has been updated in your PHP code.
If postman can do it HttpClient must be able to do it too, with the proper configuration.
Try to use all the headers postman is using you are probably missing something, maybe the filename is causing the DB query to fail.
By the way is there any difference between how you handle jpg and png in your server ? you can check that too.
I'm trying my hand at .NET Core but I'm stuck trying to convert multipart/form-data to an application/octet-stream to send via a PUT request. Anybody have any expertise I could borrow?
[HttpPost("fooBar"), ActionName("FooBar")]
public async Task<IActionResult> PostFooBar() {
HttpResponseMessage putResponse = await _httpClient.PutAsync(url, HttpContext.Request.Body);
}
Update: I think I might have two issues here:
My input format is multipart/form-data so I need to split out the file from the form data.
My output format must be application-octet stream but PutAsync expects HttpContent.
I had been trying to do something similar and having issues. I needed to PUT large files (>1.5GB) to a bucket on Amazon S3 using a pre-signed URL. The implementation on Amazon for .NET would fail for large files.
Here was my solution:
static HttpClient client = new HttpClient();
client.Timeout = TimeSpan.FromMinutes(60);
static async Task<bool> UploadLargeObjectAsync(string presignedUrl, string file)
{
Console.WriteLine("Uploading " + file + " to bucket...");
try
{
StreamContent strm = new StreamContent(new FileStream(file, FileMode.Open, FileAccess.Read));
strm.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
HttpResponseMessage putRespMsg = await client.PutAsync(presignedUrl, strm);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
return true;
}
Turns out Request has a Form property that contains a Files property that has an OpenReadStream() function on it to convert it into a stream. How exactly I was supposed to know that, I'm not sure.
Either way, here's the solution:
StreamContent stream = new StreamContent(HttpContext.Request.Form.Files[0].OpenReadStream());
HttpResponseMessage putResponse = await _httpClient.PutAsync(url, stream);
Below code uploads files on a server with same name, size and file type (like it's uploading a dummy file). But when do I try to view it, it shows noting. When I try to upload a .txt file it works. What's wrong?
public static void UploadFile(string accessToken,string path,HttpPostedFileBase file)
{
try
{
var client = new RestClient("https://content.dropboxapi.com/1/files_put/auto/Abc/" + file.FileName);
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer " + accessToken);
request.AddHeader("Content-Type", file.ContentType);
//request.AddHeader("Content-Length", file.ContentLength.ToString());
request.AddFile("file", path);
IRestResponse response = client.Execute(request);
}
catch (Exception ex)
{
throw ex;
}
}
I assume from the classes I see that you're using RestSharp? I'm not all that familiar, but from a quick search, it doesn't look like AddFile does what you want. (That sets up a multipart form upload, which is not what the Dropbox API expects.)
Instead of request.AddFile(...), I think you want something like this (completely untested):
// Get a byte array of the file content. Note that this involves reading
// the entire file into memory! I couldn't immediately find a way to work
// with the stream itself in RestSharp.
MemoryStream target = new MemoryStream();
file.InputStream.CopyTo(target);
byte[] data = target.ToArray();
// Send those bytes as the body of your HTTP request.
request.AddParameter("application/octet-stream", data, ParameterType.RequestBody);