Get the Image as a byte and send to Facebook Api - c#

I need to send an image as a Byte Array to facebook API. I try to get the file from my Mac and send it but it is breaking in second line when it is reading file.
string fileName = Path.GetFileName(request.PhotoUrl);
byte[] photoContent = File.ReadAllBytes(fileName);
I am using Mac, so my path is looks like:
"photoUrl": "/Users/myname/Documents/test.png"
It is bringing fileName is but braking in second line.

Path.GetFileName() should be returning the filename and its extension. So in your case, fileName will be set to test.png Therefore when you try to read the file your call to File.ReadAllBytes(fileName) will fail unless you are running the program from the same folder as the picture file. Instead of using Path.GetFileName() you could use Path.GetFullPath() or even just pass the PhotoUrl value to the ReadAllBytes function.
Microsoft documentation for
GetFullPath(): https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getfullpath?view=netcore-3.1
GetFileName(): https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getfilename?view=netcore-3.1

Related

C# api octet-stream response body to zip file

I have a service which executes a request to a client api that returns a octet-stream response body with the Content-Disposition header in it (This api is meant to return a zip file.). I am using RestSharp and the DownloadData function to get the response as a byte array, but I want to then save the zip file to my local server.
I have tried using DotNetZip and a MemoryStream to create the zip file by using the following example:
using (MemoryStream stream = new MemoryStream(fileBytes))
{
using (ZipFile zip = new ZipFile())
{
zip.AddEntry("test", stream);
zip.Save(filePath);
}
}
The code above creates a zip file and an entry called test but I cannot open it.
Just to clarify, the zip file I am trying to create contains the following files and folders:
296927a0-5ac7-4ccd-9928-bd74ef7ae68a_20200227074457 (Root folder)
images (folder)
jpg image
jpg image
jpg image
details.json (file)
achievements.json (file)
evaluation.json (file)
Is there any way to achieve this?
As I understood the fileBytes is already a zip file byte stream, what means you don't need to zip it again. Just save as file.
File.WriteAllBytes(filePath, fileBytes);
For anyone else who encounters this problem, as in saving the byte array to disk and getting a corrupted zip file, I have figured out the answer with the help of Dennis Tretyakov.
Basically, when downloading a octet-stream, the first section of is dedicated to the structure of the zip file. In my case the first section of the zip file was:
--c7c2ad44-881c-47c4-89e5-323f91b75269
Content-Disposition: form-data; name="deb08d79-372d-4de2-a684-1298f25fecd9_20200310142909.zip"
Content-Type: application/octet-stream
And thereafter the actual data for the zip file appears after a linebreak.
What I ended up doing was calculating the byte count of the "header" section by converting the byte array to a string:
string stringEncodedBytes = Encoding.ASCII.GetString(response.RawBytes);
Then with knowing the starting point of the zip file data, finding the index of the starting point:
int headerSectionIndex = stringEncodedBytes.IndexOf("PK");
Once I found the index, which in my case always seems to be 178, I simple removed that part of the byte array and then copy the trimmed byte array to a new byte array and write it to disk:
byte[] trimmedFileBytes = new byte[response.RawBytes.Length - headerSectionIndex];
Array.Copy(response.RawBytes, headerSectionIndex, trimmedFileBytes, 0, trimmedFileBytes.Length);
File.WriteAllBytes(filePath, trimmedFileBytes);
I would suggest that anyone struggling with the same issue, open the "corrupted" zip file in notepad++ and take a look at the first section and then determine where the data section of the zip file starts.
The initial zip file data looks like this:
And the trimmed zip file data looks like this:
So i had the same issue Dev_101 had, in which a RestResponse was corrupting the .zip file, however in my case, it was just appending an extra " on the beginning and end, so I just needed to remove the " and Base64Decode it and saved perfectly.

How to get path of Properties.Resources.Image in .NET

I included an image as a resource following this post:
How to create and use resources in .NET
I am using PDFSharp library to create a PDF. The method to draw an image, requires the path of the image. How do I get the path of Properties.Resources.Image?
Or is there another way to do this?
The Properties.Resources.Image is in-memory resource.
You can save Image to temp file and the get the path.
var path = Path.GetTempPath();
Properties.Resources.logo.Save(path);
Above uses Bitmap.Save
You can actually create an image, without saving it, using XImage.FromGdiPlusImage():
var image = XImage.FromGdiPlusImage(Properties.Resources.logo);
As of PDFsharp/MigraDoc 1.50 beta 2 and newer you no longer need a path when using MigraDoc. It was already mentioned that PDFsharp does not need a filename, as images can be read from e.g. streams.
MigraDoc still requires a string. You encode the image data as a string (BASE64 format) and pass that string as a filename.
See also:
http://pdfsharp.net/wiki/MigraDoc_FilelessImages.ashx

Corrupted images after uploading

I am having a really weird issue with my image saving method. First, here is the method:
public static void uploadImageToServer(string savePath, HttpPostedFile imageToUpload, bool overwrite)
{
byte[] myData = new Byte[imageToUpload.ContentLength];
imageToUpload.InputStream.Read(myData, 0, imageToUpload.ContentLength);
FileStream newFile = new FileStream(savePath, FileMode.Create);
newFile.Write(myData, 0, myData.Length);
newFile.Close();
}
As you can see from the input parameters this method works in conjuction with the FileUpload control. Now I am using this method from two pages which both have a FileUpload control. On one page the image uploads file, on the other page it results in a corrupted file.
I am really at a loss as to why the image is being corrupted. I am using the same image, the same method, and the same input control.
Is there any way I can debug this?
Gonna steal alexn's answer <_<
You are over-complicating it. Just use the built-in FileUpload::SaveAs(save_path) that is provided for you.
You can use the Server.MapPath() method to help you get a dynamic path to your root directory, go from there and append the file name to it.
Not sure why you are getting that error. My best guess is either your savePath is broken (or the filename/extension appended to it), or the bytes are not being read/written to perfectly.. Anyway, you should not get that error by using the method I described (considering you don't mess up the file extension :).

How to download a file without extension in C#

Okay so I want to download a file from a website, but the file is lacking an extension.
(it's an image file, I know this much, but the link does not provide the actual extension)
When I use webrequest, or webclient to download the file I get a "404 file not found" exception.
WebClient wc = new WebClient();
Stream strm = wc.DownloadFile("http://some_site.some_domain/some_image.","C:/some_directory/save_name.some_extention");
Notice the lack of extention at the end of the URL.
The site in question displays the image fine in a webbrowser, but when viewing just the image there is no extension and thus it's treated an unknown file (not showing an image).
So simply put: how do I download a file if there is no extention specified?
Thanks in advance!
So you're trying to determine what extension to give the file after downloading? If the URL doesn't have one you would have to inspect the actual data of the file.
You might be able to inspect the beginning of the file and see if it matches known valid file types. For instance, PNGs seem to have 'PNG' as bytes 2-4 (at least in the ones I've inspected). By looking at that data you should be able to determine the format with a fairly high accuracy.
This would be my best suggestion, if this doesn't work I don't know how to solve you problem...
List<string> fileExtensions = new List<string>(){"png","gif","bmp","jpg"}// other known image file extensions here...
WebClient wc = new WebClient();
foreach(var extension in fileExtensions)
{
try
{ wc.DownloadFile("http://some_site.some_domain/some_image."+extension,"C:/some_directory/save_name."+extension);
break;
}
catch {}
}
This would just be a work around, I guess... Not a real solution...

Byte[] Array to String

I want to output a Byte[] array to a string so I can send it along a HTTPRequest. Can it be done? And will the server pick up the data and create a file from it? Or does some special encoding need to be done?
The file is an image. At the moment I have:
Byte[] fBuff = File.ReadAllBytes("C:/pic.jpeg");
I need to take what's in fBuff and output it to send along a post request.
Use the Convert.ToBase64String method
Byte[] fBuff = File.ReadAllBytes("C:/pic.jpeg");
String base64 = Convert.ToBase64String(fBuff);
This way the string will as compact as posible and is sort of the "standard" way to writing bytes to string and back to bytes.
To convert back to bytes use Convert.FromBase64String:
String base64 = ""; // get the string
Byte[] fBuff = Convert.FromBase64String(base64);
You could just create a String where each byte is a character of the String. If you do the same opposite procedure at the receiver you will not have any problems (I have done something similar but in Java).
Convert.ToBase64String looks like your best option to store the bytes in a transmittable array, you should look into these functions.
If you are sending just the file, you can use the UploadFile method of the WebClient class:
using (WebClient client = new WebClient) {
client.UploadFile("http://site.com/ThePage.aspx", #"C:\pic.jpeg");
}
This will post the file as a regular file upload, just as from a web page with a file input. On the receiving server the file comes in the Request.Files collection.
Any reason of not using the WebClient upload file?

Categories

Resources