C
C#2y ago
Kaedrick

❔ Problem with image hosting API

Hello, I tried to upload an image to an image hosting API but no matter what I do I get the following error : System.Net.WebException: 'The remote server returned an error: (400) Bad Request.' (see screenshot). Code :
C#
MemoryStream stream = new MemoryStream(); // Stream that will contain the image bytes (can't upload an image straight to SQL db)
productImage.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Png); // saves the image to byte in the object "stream"
byte[] picture = stream.ToArray();
string picture64 = Convert.ToBase64String(picture);

using (WebClient wc = new WebClient()) // API pour upload l'image sur un serveur et foutre le lien dans la db
{
string URL = "https://thumbsnap.com/api/upload";
string parameters = "key=censored&media=" + picture64;
wc.Headers[HttpRequestHeader.ContentType] = "multipart/form-data";
string htmlResult = wc.UploadString(URL, parameters);
}
C#
MemoryStream stream = new MemoryStream(); // Stream that will contain the image bytes (can't upload an image straight to SQL db)
productImage.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Png); // saves the image to byte in the object "stream"
byte[] picture = stream.ToArray();
string picture64 = Convert.ToBase64String(picture);

using (WebClient wc = new WebClient()) // API pour upload l'image sur un serveur et foutre le lien dans la db
{
string URL = "https://thumbsnap.com/api/upload";
string parameters = "key=censored&media=" + picture64;
wc.Headers[HttpRequestHeader.ContentType] = "multipart/form-data";
string htmlResult = wc.UploadString(URL, parameters);
}
62 Replies
Angius
Angius2y ago
First and foremost, use HttpClient not WebClient. The latter is obsolete and should not be used And the API wants a POST request with form-data content Not data sent as a query string
Kaedrick
KaedrickOP2y ago
Thank you I'm gonna change webclient to httpclient, but I don't get the part about the POST request (sry beginner here)
Angius
Angius2y ago
HTTP requests can have different types and send data in various ways GET is for getting, POST is for sending, PATCH for updating, etc The data can be sent as a query string like ?foo=1&bar=hello, which is used for GET requests There are other ways, like multipart/form-data that supports sending files Or application/json that lets you send structured data
Angius
Angius2y ago
The API docs say
Kaedrick
KaedrickOP2y ago
okay uhh sorry just got back, imma try to understand it all yeah I don't get it at all lol I have no clue where to start or even what to do with my code
Angius
Angius2y ago
tl;dr is, you need to send a POST request with multipart/form-data data
Angius
Angius2y ago
MAKOLYTE
C# - How to send a file with HttpClient | MAKOLYTE
Shows how to send a file in a multipart/form-data request using HttpClient by loading it into a MultipartFormDataContent object
Angius
Angius2y ago
Like in this code, except you'd add one more field to the formdata The field with your API key
Kaedrick
KaedrickOP2y ago
tyvm I'll try to make it work somehow <:br_laugh:742854844301312031>
Angius
Angius2y ago
Yeah, feel free to ask again if the code still doesn't want to work
Kaedrick
KaedrickOP2y ago
I still can’t get it to work lol I have no clue how any of this works, I’ll just get some sleep and watch a few tutorials tomorrow I guess Thanks a lot btw
Angius
Angius2y ago
No problem, anytime 👌
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Kaedrick
KaedrickOP2y ago
Still not fixed no I feel like this is way above my very beginner level lol
Angius
Angius2y ago
Show your current code We'll see what's up
Kaedrick
KaedrickOP2y ago
I deleted most of it to try and start from the beginning, but my problem is with this : https://makolyte.com/csharp-how-to-send-a-file-with-httpclient/ In this example, he sends a file from a predefined path, which is not what I want, I want to send an image that the user chooses from his computer, and secondly, he sends it to a server while I am trying to just use an image hosting API, which I don't know how to change for my usage
MAKOLYTE
C# - How to send a file with HttpClient | MAKOLYTE
Shows how to send a file in a multipart/form-data request using HttpClient by loading it into a MultipartFormDataContent object
Kaedrick
KaedrickOP2y ago
I'll post code when I make some progress lol
Angius
Angius2y ago
I want, I want to send an image that the user chooses from his computer
So get the path to the file from the user
he sends it to a server while I am trying to just use an image hosting API
Where do you believe does the API run? localhost:6001 and https://mycoolwebsite.com are the same thing, fundamentally
Kaedrick
KaedrickOP2y ago
yeah lol I know it's from a server but he just hosts it to some localhost link and not using an API with the key etc so idk how to proceed Is there any way to get a file path automatically from a file selection dialog ?
Angius
Angius2y ago
That's actually what the file dialog gives you, the path And the link to localhost is no different than the link to the API
Kaedrick
KaedrickOP2y ago
ThinkingFast
Angius
Angius2y ago
Literally the same exact thing
Kaedrick
KaedrickOP2y ago
yeah I know but where does the key go then
Angius
Angius2y ago
Into the form data
MODiX
MODiX2y ago
Angius#1586
Like in this code, except you'd add one more field to the formdata
Quoted by
React with ❌ to remove this embed.
Kaedrick
KaedrickOP2y ago
okay thanks Imma try to understand it all because even syntax is complicated to me lol i'll get back to you, tyvm hey uh I'm confused about something
Kaedrick
KaedrickOP2y ago
Angius
Angius2y ago
Shoot $scopes
MODiX
MODiX2y ago
scope A {
thing a;
scope B {
thing b;
}
}
scope A {
thing a;
scope B {
thing b;
}
}
thing a is available in scope A and scope B thing b is available only in scope B
Kaedrick
KaedrickOP2y ago
how do I access this variable if it's in a private class ? I'm pretty sure I can't but it's private by default and I4m not sure changing it is a good idea
Angius
Angius2y ago
Just place it on the class level
class Foo
{
private int _num;

private void SomeMethod()
{
_num = 69420;
}

private void SomeOtherMethod();
{
Console.WriteLine($"Num is {_num}");
}
}
class Foo
{
private int _num;

private void SomeMethod()
{
_num = 69420;
}

private void SomeOtherMethod();
{
Console.WriteLine($"Num is {_num}");
}
}
Kaedrick
KaedrickOP2y ago
very confused as in how to do that here
Angius
Angius2y ago
Just put the variable on the class level
Kaedrick
KaedrickOP2y ago
but if I do that it won't recognize productPicture.Filename; anymore
Angius
Angius2y ago
private string filePath on the class level
Kaedrick
KaedrickOP2y ago
ohhhhhhhh
Angius
Angius2y ago
filePath = productPicture.Filename in one method var filePath = filePath in the other Or just... use the class-level filePath
Kaedrick
KaedrickOP2y ago
I thought I had it but no, I'm dense I think
Angius
Angius2y ago
Angius
Angius2y ago
See my edits in lime green
Kaedrick
KaedrickOP2y ago
woah it works tyvm, just trying to understand, what's the "_" for ?
Angius
Angius2y ago
Just a naming convention Private fields have the _ in front Mostly for use in the constructors With _
class Foo
{
private int _foo;
public Foo(int foo)
{
_foo = foo;
}
}
class Foo
{
private int _foo;
public Foo(int foo)
{
_foo = foo;
}
}
Without _
class Foo
{
private int foo;
public Foo(int foo)
{
this.foo = foo;
}
}
class Foo
{
private int foo;
public Foo(int foo)
{
this.foo = foo;
}
}
Kaedrick
KaedrickOP2y ago
okay I think I get it thanks 🙂 so in the page you sent me to send the image to an API, regarding this section :

var filePath = @"C:\house.png";

using (var multipartFormContent = new MultipartFormDataContent())
{
//Load the file and set the file's Content-Type header
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");

//Add the file
multipartFormContent.Add(fileStreamContent, name: "file", fileName: "house.png");

var filePath = @"C:\house.png";

using (var multipartFormContent = new MultipartFormDataContent())
{
//Load the file and set the file's Content-Type header
var fileStreamContent = new StreamContent(File.OpenRead(filePath));
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");

//Add the file
multipartFormContent.Add(fileStreamContent, name: "file", fileName: "house.png");
I'm not sure how to proceed since "house.png" has to be the selected file name here, and that "image/png" should be "image/whatever the chosen image format is" woops not sure why it quoted the c# part too
Angius
Angius2y ago
$codegif
Angius
Angius2y ago
You need cs not c# And you can get the MIME type from the extension
MODiX
MODiX2y ago
Angius#1586
REPL Result: Success
var file = "house.png";
var mime = $"image/{file.Split('.')[^1]}";
mime
var file = "house.png";
var mime = $"image/{file.Split('.')[^1]}";
mime
Result: string
image/png
image/png
Compile: 510.352ms | Execution: 41.514ms | React with ❌ to remove this embed.
Kaedrick
KaedrickOP2y ago
okay that actually is cool, and for once I understand lol thanks one more thing before I go to sleep and do the rest tommorow how do I get the chosen file name, since "productPicture.FileName" actually returns the picture's whole path and not just its name ?
Angius
Angius2y ago
You can split by the path separator and take the last chunk Or you can use Uri class, I believe Or maybe the Path class One of the two The constructor will take the whole path, and then you'll be able to take whatever from the object
Kaedrick
KaedrickOP2y ago
so if the full path is : C:\Users\secret\OneDrive\Images\secret.png how do I split it so it always takes what comes after the last "" ? *the last " \ "
MODiX
MODiX2y ago
Angius#1586
REPL Result: Success
@"C:\Users\secret\OneDrive\Images\secret.png".Split('\\')[^1]
@"C:\Users\secret\OneDrive\Images\secret.png".Split('\\')[^1]
Result: string
secret.png
secret.png
Compile: 470.377ms | Execution: 35.245ms | React with ❌ to remove this embed.
Angius
Angius2y ago
Like this
MODiX
MODiX2y ago
Kaedrick#5670
REPL Result: Success
@"C:\secret\OneDrive\secret.png".Split('\\')[^1]
@"C:\secret\OneDrive\secret.png".Split('\\')[^1]
Result: string
secret.png
secret.png
Compile: 447.716ms | Execution: 36.233ms | React with ❌ to remove this embed.
Kaedrick
KaedrickOP2y ago
ok it works even if there's less " \ " in the path
Angius
Angius2y ago
[ a, b, c, d, e ]
0 1 2 3 4
^5 ^4 ^3 ^2 ^1
[ a, b, c, d, e ]
0 1 2 3 4
^5 ^4 ^3 ^2 ^1
Kaedrick
KaedrickOP2y ago
perfect tyvm!
Angius
Angius2y ago
With ^ you can index from the end
Kaedrick
KaedrickOP2y ago
ohhh tyvm!! can you explain why there's 2 \ ? just to be sure i understand in (' \ ') ffs it won't let me lol
Angius
Angius2y ago
\ is the escape character So '\' is treated as "character delimiter, then literal apostrophe" A closing character delimiter is, thus, missing '\\' is "character delimiter, literal backslash, character delimiter"
Kaedrick
KaedrickOP2y ago
oh okay! thank you so much you were so helpful I feel like maybe tomorrow or the day after I'll have this damn API upload thing working <:gx_Sunglasses_cry:750469526667264051> but for now, some sleep good night sir
Angius
Angius2y ago
'Night
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server