C
C#2y ago
Waranai

✅ Fetch

hi 🙂 so, i have small problem with sending form with image to server, can someone please explain how to correctly do that? spend like 3 hours and not found anything useful about that 😦
<form id="formq">
<p>
<label for="title" method="post">Title</label>
</p>
<input type="text" id="title" name="title" required>

<p>
<label for="description">description</label>
</p>
<input type="description" id="description" name="description" required>

<p>
<label for="price">price</label>
</p>
<input type="price" id="price" name="price" required>

<label for="image">price</label>
<input type="file" id="image" name="image" required>
<p>
<button type="submit">Add product</button>
</p>
</form>
<form id="formq">
<p>
<label for="title" method="post">Title</label>
</p>
<input type="text" id="title" name="title" required>

<p>
<label for="description">description</label>
</p>
<input type="description" id="description" name="description" required>

<p>
<label for="price">price</label>
</p>
<input type="price" id="price" name="price" required>

<label for="image">price</label>
<input type="file" id="image" name="image" required>
<p>
<button type="submit">Add product</button>
</p>
</form>
that is endpoint for request, but have no clue how to send image with,
app.MapPost("/api/addProduct", [Authorize] (ProductM prod, ShopDbContext db) =>
{

string fileName = Guid.NewGuid().ToString();
// save file in folder with new name
// create Product based on data
// save to db
return Results.Ok();
});
app.MapPost("/api/addProduct", [Authorize] (ProductM prod, ShopDbContext db) =>
{

string fileName = Guid.NewGuid().ToString();
// save file in folder with new name
// create Product based on data
// save to db
return Results.Ok();
});
like, in case of registration i was sending it like -
const response = await fetch("api/register", {
method: "POST",
headers: { "Accept": "application/json", "Content-Type": "application/json" },
body: JSON.stringify({
name: document.getElementById("name").value,
email: document.getElementById("email").value,
password: document.getElementById("password").value
})
});
const response = await fetch("api/register", {
method: "POST",
headers: { "Accept": "application/json", "Content-Type": "application/json" },
body: JSON.stringify({
name: document.getElementById("name").value,
email: document.getElementById("email").value,
password: document.getElementById("password").value
})
});
but with images its a bit harder, tried with byte array but don't worked
40 Replies
Waranai
WaranaiOP2y ago
btw, with HttpConext i think i even know how to do that, but don't rly want to use it, cuz should be better way
Angius
Angius2y ago
To send an image you need a multipart/form-data request, not an application/json one
Waranai
WaranaiOP2y ago
ok finally i get it need to make my own class which uses IFormFile or somehow read data from IfromFileCollection another quest getting something like this - ????JFIFHH??C   %-(0%()(??C  (((((((((((((((((((((((((((((((((((((((((((((((((((??  "?????? ?zC??????itCWs=???????6???8???!?VWD?????{|????????????gM?Y??'P?+=c????TY+?Nl?m?????????|>?2???ßV4??;wC{q!??5?m?Y??-k?9?'@+X.? 9???5X?,?U???iO ?O(????:;??b?f2??y????<?L???l?~ ????f??\???????Uw?)pO????KD??{?>??q??{}?|W?Q>tJD???????T?r??OV????2H0|??r?hX?z?G?>????&}j?,X6`?}O>?:9E????V4??H?Xb???bt ?Y>??7??vk??9u&?1??O????F?7~jtR??????;??f?.??l$~L?b?Y????U???????O5??)? ?g??Q??0?????MM?iC???f>??g'???b???????xOYUYkX?????lf?/T???I???3d/=H?]=?|?V?JL??u??y?w???Rg ????????}o?s|?L?o?m?M?J>>????r ??^?????<y??m?X?G>??;f?E<???j<??F?r??R?H???h??|?y/?J?1?~? p???A{?#h?5??)?????C???d?m????/|??e???{???{Q"2????X??2#4zy?A^<?5|^????? o:?G(mj?}?zZ?(??mT?g?6u?>?=????{44??t??L?s???OW87??fr??o?1@??r?????ì?k???|?^z?S,????"?|I??W???z?~v?????yt??pL|K?ty5 ,?????K???R0???xG??????4?=~???i>?N?/????? ????#?y5 &=??^?MbC?D?C????A??2??DE??u??<6??u?C??XCD?????=N?~4d7@???{?;.?;G?|sP????X?6???fy4??o???y???eS???,?i?p?L???tv???n0z?n?Un?(?O;?????j?s>?'??L???g?9??2?C????????????~}tj???0{?1?gF??;?,<??o??????'??????J=?S?<???-uM???1???d?????J?v?g????zLC???td~?x??q?&b'k??????iR2?J?V?l?u{^???" ?α/?Σ?s??:??}??????}O?E:zC?j?E????_D???FK}? ?J?f?d??@l^????{???<??qzD}v?H>;7&?$????g7???r>??M@=?P??h?]??z??;?y?$?^`??????+?C?????Cq???&h?R???t??=??m?V??U???C?t?? vM?<??;??r(?|???K^?Z-g???k???o-q8?]???1P:$9F??3?n?r[?ZQc?1R?<?T?????0???????Z??T??*0??%??f?k?U??{?o????BEh??????/?%
Waranai
WaranaiOP2y ago
Waranai
WaranaiOP2y ago
app.MapPost("/api/addProduct", [Authorize] async ([FromForm] IFormFileCollection collection, ShopDbContext db) =>
{
IFormFile? file = collection.FirstOrDefault();
if (file is null)
return Results.BadRequest("Bad image");

string uniqueFileName = Guid.NewGuid().ToString();
string filePath = Path.Combine("StaticFiles/Images", uniqueFileName);

using (var fs = new FileStream(filePath, FileMode.Create))
await file.CopyToAsync(fs);

return Results.Ok();
});
app.MapPost("/api/addProduct", [Authorize] async ([FromForm] IFormFileCollection collection, ShopDbContext db) =>
{
IFormFile? file = collection.FirstOrDefault();
if (file is null)
return Results.BadRequest("Bad image");

string uniqueFileName = Guid.NewGuid().ToString();
string filePath = Path.Combine("StaticFiles/Images", uniqueFileName);

using (var fs = new FileStream(filePath, FileMode.Create))
await file.CopyToAsync(fs);

return Results.Ok();
});
finally, got my image but where is other harold
Pobiega
Pobiega2y ago
You dont have a field for it, so where do you expect it to go?
Waranai
WaranaiOP2y ago
idk bro, im doing it 6 hours already, on start i had it somehow and lost logic while sloving image problem lmao
Pobiega
Pobiega2y ago
Try adding it back in, also with fromform attribute As far as I can tell you replaced your product dto with the formfilecollection (are you uploading multiple files?) If single file, don't use collection
Waranai
WaranaiOP2y ago
idk, it just wasn't working with IFormFile
Waranai
WaranaiOP2y ago
Waranai
WaranaiOP2y ago
app.MapPost("/api/addProduct", [Authorize] async ([FromForm] ProductFormData model, [FromForm] IFormFileCollection collection, ShopDbContext db) =>
{
System.Console.WriteLine(model.Title);
IFormFile? file = collection.FirstOrDefault();
if (file is null)
return Results.BadRequest("Bad image");

string uniqueFileName = Guid.NewGuid().ToString();
string filePath = Path.Combine("StaticFiles/Images", uniqueFileName);

using (var fs = new FileStream(filePath, FileMode.Create))
await file.CopyToAsync(fs);

return Results.Ok();
});
app.MapPost("/api/addProduct", [Authorize] async ([FromForm] ProductFormData model, [FromForm] IFormFileCollection collection, ShopDbContext db) =>
{
System.Console.WriteLine(model.Title);
IFormFile? file = collection.FirstOrDefault();
if (file is null)
return Results.BadRequest("Bad image");

string uniqueFileName = Guid.NewGuid().ToString();
string filePath = Path.Combine("StaticFiles/Images", uniqueFileName);

using (var fs = new FileStream(filePath, FileMode.Create))
await file.CopyToAsync(fs);

return Results.Ok();
});
Pobiega
Pobiega2y ago
Ok, try removing the attribute from the dto, see if it binds
Waranai
WaranaiOP2y ago
Waranai
WaranaiOP2y ago
if i correctly understood what to remove
Pobiega
Pobiega2y ago
Hm Well, it thought it should bind to body, but we want it to bind to the form Idk enough about minimal APIs to solve this
Waranai
WaranaiOP2y ago
same, lmao atleast i got image, so can figure out other ways how to get data
Pobiega
Pobiega2y ago
What .net version?
Waranai
WaranaiOP2y ago
should be latest i mean 7, no?
Pobiega
Pobiega2y ago
Ok. 6 does not support binding to form data, unsure about 7
Waranai
WaranaiOP2y ago
Pobiega
Pobiega2y ago
Stack Overflow
.NET 6 Minimal API and multipart/form-data
Using the .NET 6 Minimal API, I'm trying to handle multipart/form-data in the POST method. However, with the following code: app.MapPost("/tickets", async (IFreshdeskApiService s, [FromFo...
Pobiega
Pobiega2y ago
This is for 6, but might be worth a read
Waranai
WaranaiOP2y ago
i mean with HttpContextn i think its easy to do problem is to do this without context
Pobiega
Pobiega2y ago
Pobiega
Pobiega2y ago
Read the center post by fowler This is literally unsupported and not possible without a custom modelsbinder or using the context
Waranai
WaranaiOP2y ago
harold
Pobiega
Pobiega2y ago
Or use a controller:p
Waranai
WaranaiOP2y ago
mvc is next course for me, will start in 5-8 days
Pobiega
Pobiega2y ago
Apparently .net 8 preview supports it For simple models Ie no nested stuff or lists
Pobiega
Pobiega2y ago
Pobiega
Pobiega2y ago
Wait what You had a course on minimal APIs before controllers? Thats wild. Minimal APIs are still new, education tends to lag behind
Waranai
WaranaiOP2y ago
Its separated courses, was up to me which one i start with
Waranai
WaranaiOP2y ago
asked some guys and they said this way is ok
Waranai
WaranaiOP2y ago
start with core after mvc and after razor pages
Pobiega
Pobiega2y ago
Asp.net core doesn't imply either minimal or MVC or razor
Waranai
WaranaiOP2y ago
i mean, atleast i know how this works
app.MapPost("/api/addProduct", [Authorize] async (HttpContext context, [FromForm] IFormFileCollection collection, ShopDbContext db) =>
{
IFormFile? file = collection.FirstOrDefault();
if (file is null)
return Results.BadRequest("Bad image");

string uniqueFileName = Guid.NewGuid().ToString() + file.FileName;
string filePath = Path.Combine("StaticFiles/Images", uniqueFileName);

using (var fs = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(fs);
}

Product product = new Product
{
Id = db.Products.Count() + 1,
Title = context.Request.Form["Title"],
Description = context.Request.Form["Description"],
Price = Convert.ToDecimal(context.Request.Form["Price"]),
Image = uniqueFileName
};

db.Products.Add(product);
db.SaveChanges();
return Results.Ok();
});
app.MapPost("/api/addProduct", [Authorize] async (HttpContext context, [FromForm] IFormFileCollection collection, ShopDbContext db) =>
{
IFormFile? file = collection.FirstOrDefault();
if (file is null)
return Results.BadRequest("Bad image");

string uniqueFileName = Guid.NewGuid().ToString() + file.FileName;
string filePath = Path.Combine("StaticFiles/Images", uniqueFileName);

using (var fs = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(fs);
}

Product product = new Product
{
Id = db.Products.Count() + 1,
Title = context.Request.Form["Title"],
Description = context.Request.Form["Description"],
Price = Convert.ToDecimal(context.Request.Form["Price"]),
Image = uniqueFileName
};

db.Products.Add(product);
db.SaveChanges();
return Results.Ok();
});
finally that thing works
Waranai
WaranaiOP2y ago
Waranai
WaranaiOP2y ago
Waranai
WaranaiOP2y ago
Waranai
WaranaiOP2y ago
Thanks for help @Pobiega , without you I would have sat there for 10 hours wondering whats wrong.

Did you find this page helpful?