C
C#16mo ago
wwww

✅ SQL and images

Hi, so, i made this thing (screenshots), and what should i do with images, i mean, which is most used way to deal with images?
44 Replies
Angius
Angius16mo ago
What do you mean "deal with"? As in, how to store them? Store them in a CDN or at least the filesystem, and save their location in the database
wwww
wwwwOP16mo ago
file stream is the first thing that came to my mind, and how, is that ok?(just wanted to ask because sometimes you can do something and after someone tells you, there is something specifically for that and you could have done it much easier) ? or is it better to figure out how to work with this "cdn" thing?
Angius
Angius16mo ago
Uh file stream is a way to read or write a file from/to a disk So yes, you can use it to do that
wwww
wwwwOP16mo ago
so, like here, but instead of html file, im reading image and after putting that file in db
Angius
Angius16mo ago
If you want to send the file manually, sure Or use the static files middleware
wwww
wwwwOP16mo ago
got something like this, Product class, generated by EFc.
public partial class Product
{
public int Id { get; set; }

public string Title { get; set; } = null!;

public string? Description { get; set; }

public decimal Price { get; set; }

public byte[]? Image { get; set; } = File.ReadAllBytes("Images/missing.jpg");
}
public partial class Product
{
public int Id { get; set; }

public string Title { get; set; } = null!;

public string? Description { get; set; }

public decimal Price { get; set; }

public byte[]? Image { get; set; } = File.ReadAllBytes("Images/missing.jpg");
}
app.Map("/api/products", (ShopDbContext db) => db.Products);
app.Map("/api/products", (ShopDbContext db) => db.Products);
window.onload = async () => {
var response = await fetch("/api/products", {
method: "GET",
headers: { "Accept": "application/json" }
});

if (!response.ok)
console.log(console);

const data = await response.json();
console.log(data);
data.forEach(async product => {
const prod = `<div class="product">
<img src="data:image/jpeg;base64,${product.image}" class="productImage">
<p> ${product.title} | ${product.price}$ </p>
</div>`;
document.querySelector("[data-content]").insertAdjacentHTML("beforeend", prod);
});
};
window.onload = async () => {
var response = await fetch("/api/products", {
method: "GET",
headers: { "Accept": "application/json" }
});

if (!response.ok)
console.log(console);

const data = await response.json();
console.log(data);
data.forEach(async product => {
const prod = `<div class="product">
<img src="data:image/jpeg;base64,${product.image}" class="productImage">
<p> ${product.title} | ${product.price}$ </p>
</div>`;
document.querySelector("[data-content]").insertAdjacentHTML("beforeend", prod);
});
};
wwww
wwwwOP16mo ago
wwww
wwwwOP16mo ago
and got this (all images are same cuz default value)
wwww
wwwwOP16mo ago
stored in db as byte array
Angius
Angius16mo ago
All of that after me telling you to not save images in the database, huh?
wwww
wwwwOP16mo ago
wait don't rly get it where should i save them if not in db? oh i remember i mean, have seen i need to save images in specific folders and save path to them in db?
Angius
Angius16mo ago
Yep
wwww
wwwwOP16mo ago
and when i need to send image, then i make byte array right?
Angius
Angius16mo ago
Well, depends how you want to send those images Because if you use a form, or a form-style request, you can just use an IFormFile If not then yeah, I guess you can encode the image as Base64 and send it as a part of the JSON request
wwww
wwwwOP16mo ago
ok, i got this thing and gonna rewrite code btw, anyway topic about images is open, in case of adding product in db, im just getting byte array from request body, generating random name while(db.Count(p => p.Image == [randomly generated name]) == 0, and saving this image into images folder with this name. and after i save product in db, where Image is string and value is randomly generated name. or maybe there is better ways to do that? @ZZZZZZZZZZZZZZZZZZZZZZZZZ
Angius
Angius16mo ago
A randomly generated name is fine, yeah You can use a GUID to make sure there are no collisions too
wwww
wwwwOP16mo ago
when i said [randomly generated name]. i meant guid (have seen some examples of it (but not overcommitted)), it still can generate same name, or no?
Angius
Angius16mo ago
Yes, but the chances of that are incredibly unlikely
wwww
wwwwOP16mo ago
ok, thx badhun1UA closed to early 🙂 so, instead of sending data like this (first code), im writing new logic and sending list of anonyms objects or what (second code)? @ZZZZZZZZZZZZZZZZZZZZZZZZZ
app.Map("/api/products", (ShopDbContext db) => db.Products);
app.Map("/api/products", (ShopDbContext db) => db.Products);
app.Map("/api/products", (ShopDbContext db) =>
{
var list = new List<object>();
foreach (Product prod in db.Products)
{
var product = new
{
title = prod.Title,
price = prod.Price,
image = GetImageByName(prod.Image)
};
list.Add(product);
}
Results.Json(list);
});
app.Map("/api/products", (ShopDbContext db) =>
{
var list = new List<object>();
foreach (Product prod in db.Products)
{
var product = new
{
title = prod.Title,
price = prod.Price,
image = GetImageByName(prod.Image)
};
list.Add(product);
}
Results.Json(list);
});
or should i make whole new class, like, ProductToSent, and fill this class using info from prod object?
Angius
Angius16mo ago
Ideally, yes, make a proper class (or a record at least) to describe the data Actually, a record might be easier and more proper here
wwww
wwwwOP16mo ago
yeap, already started
public class ProductPreview
{
public int Id { get; set; }

public string Title { get; set; } = null!;

public string? Description { get; set; }

public decimal Price { get; set; }

public byte[] Image { get; set; }

public ProductPreview(int id, string title, string description, decimal price, byte[] image)
{
Id = id;
Title = title;
Description = description;
Price = price;
Image = image;
}
}
public class ProductPreview
{
public int Id { get; set; }

public string Title { get; set; } = null!;

public string? Description { get; set; }

public decimal Price { get; set; }

public byte[] Image { get; set; }

public ProductPreview(int id, string title, string description, decimal price, byte[] image)
{
Id = id;
Title = title;
Description = description;
Price = price;
Image = image;
}
}
finally got something like this
app.Map("/api/products", (ShopDbContext db) =>
{
var list = new List<ProductPreview>();
foreach (Product prod in db.Products)
if (prod.Description != null && prod.Image != null)
list.Add(new ProductPreview(prod.Id, prod.Title, prod.Description, prod.Price, GetImageByName(prod.Image).Result));

return Results.Json(list);
});
app.Map("/api/products", (ShopDbContext db) =>
{
var list = new List<ProductPreview>();
foreach (Product prod in db.Products)
if (prod.Description != null && prod.Image != null)
list.Add(new ProductPreview(prod.Id, prod.Title, prod.Description, prod.Price, GetImageByName(prod.Image).Result));

return Results.Json(list);
});
static async Task<byte[]> GetImageByName(string name)
{
byte[] file = await File.ReadAllBytesAsync($"Images/{name}");
return file;
}
static async Task<byte[]> GetImageByName(string name)
{
byte[] file = await File.ReadAllBytesAsync($"Images/{name}");
return file;
}
wwww
wwwwOP16mo ago
works well
Angius
Angius16mo ago
.Result this is a no-no Also, not sure why you're reding the image into memory and then returning the bytes Instead of using the static dile middleware and just returning the URL
wwww
wwwwOP16mo ago
i just don't know what is it, lmao, ok looks like need to see what this thing do
Angius
Angius16mo ago
It's a one line in your Program.cs that will make it so ASP will automatically serve all files from /wwwroot directory So if you have /wwwroot/images/cat.png you'll be able to just have <img src="/images/cat.png" /> in your HTML and it'll work
wwww
wwwwOP16mo ago
yeah, i know it, using for that thing
wwww
wwwwOP16mo ago
should i save all images here or what u mean?
Angius
Angius16mo ago
ye
wwww
wwwwOP16mo ago
oh, i thought static files ar about sending some default things, like logos, animations ect, not for user data and wanted to make server side folder of images to send only required images
Angius
Angius16mo ago
I mean, it will still send only the required image
wwww
wwwwOP16mo ago
oh, then it looks super easy expect 1 thing image type
Angius
Angius16mo ago
Whatever The middleware will choose the correct mime type Unless you meant to ask about what's the best image type to use In which case, AVIF -> WEBP -> PNG
wwww
wwwwOP16mo ago
i mean, i want to add image upload later
Angius
Angius16mo ago
Yea
wwww
wwwwOP16mo ago
and users can upload different types but looks like
Angius
Angius16mo ago
Yep
wwww
wwwwOP16mo ago
i have to change type to what i want
Angius
Angius16mo ago
You can, sure
wwww
wwwwOP16mo ago
or its not rly matter?
Angius
Angius16mo ago
But you don't have to
wwww
wwwwOP16mo ago
ok, makes sanse soooo then 1 sec. oh nice
app.Map("/api/products", (ShopDbContext db) => db.Products);
app.Map("/api/products", (ShopDbContext db) => db.Products);
const data = await response.json();
data.forEach(async product => {
const prod = `<div class="product">
<img src="${product.image}" class="productImage">
<p> ${product.title} | ${product.price}$ </p>
</div>`;
document.querySelector("[data-content]").insertAdjacentHTML("beforeend", prod);
});
const data = await response.json();
data.forEach(async product => {
const prod = `<div class="product">
<img src="${product.image}" class="productImage">
<p> ${product.title} | ${product.price}$ </p>
</div>`;
document.querySelector("[data-content]").insertAdjacentHTML("beforeend", prod);
});
don't even need this preview class anymore and i just store my image in static files folder and that is?
Angius
Angius16mo ago
ye
wwww
wwwwOP16mo ago
🤯 Thanks as always. thats rly saved my head from burnout
Angius
Angius16mo ago
Ok

Did you find this page helpful?