I need to save pictures in the file directory. Data is already being saved in the database. But I want to save an image. I do not have a proper understanding of that
Angular Form
<form [formGroup]="myForm" (ngSubmit)="submit()">
<mat-card>
<h2 >Product Management</h2>
<label for="">Product Name</label>
<input type="text" name="name" id="name" formControlName="ProductName" >
<input type="text" name="description" id="description" placeholder="Product Description" formControlName="ProductDescription">
<input type="text" name="price" id="price" placeholder="Product Price" formControlName="price">
<input type="text" name="created" id="created" placeholder="Product created" formControlName="created">
<input type="text" name="cat" id="cat" placeholder="Product created" formControlName="ProductCatID">
<input type="file" name="Image" id="Image" (change)="onFileChange($event)" formControlName="ImageUrl">
<img [src]="imageSrc" *ngIf="imageSrc" style="height: 300px; width:500px">
<button type="submit" >Submit</button>
</mat-card>
</form>
Angular TS file
submit(){
console.log(this.myForm.value);
this.http.post('https://localhost:5001/api/Products', this.myForm.value)
.subscribe(res => {
console.log(res);
alert('Uploaded Successfully.');
})
}
I think there is no problem with the angular part.
Web API Controller
[HttpPost]
public ActionResult<ProductDto> CreateProduct(CreateProductDto pro)
{
try
{
var productEntity = _mapper.Map<Product>(pro);
var newProduct = _SqlService.AddProduct(productEntity);
var productForReturn = _mapper.Map<ProductDto>(newProduct);
return CreatedAtRoute("GetProduct", new { id = productForReturn.ProId },
productForReturn);
}
catch(Exception ex)
{
return StatusCode(500, $"Internal server error: {ex}");
}
}
This is the Model class
public class Product
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ProId { get; set; }
[Required]
[StringLength(255)]
public string ProductName { get; set; }
[Required]
[StringLength(255)]
public string ProductDescription { get; set; }
[Required]
[Column(TypeName = "decimal(18, 2)")]
public decimal price { get; set; }
public DateTime created { get; set; }
public int ProductCatID { get; set; }
public ProductCat Category { get; set; }
[StringLength(255)]
public string ImageUrl { get; set; }
}
This is Create Dto class
public class CreateProductDto
{
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public decimal price { get; set; }
public DateTime created { get; set; }
public int ProductCatID { get; set; }
public string ImageUrl { get; set; }
}
This is my SQL Service Code
public Product AddProduct(Product product)
{
_context.Products.Add(product);
_context.SaveChanges();
return _context.Products.Find(product.ProId);
}
CodePudding user response:
"I need to save pictures in the file directory. Data is already being saved in the database. But I want to save an image. I do not have a proper understanding of that"
Well, let's assume we want to upload
product image
in theimage folder
underwwwroot
within our application. Just like the image below:The common scenario in our daily development life cycle is, to save the image into a desired folder within the application and save that
image name
orimage path location
into the database which is the best practice so far.
Your Current Scenario:
As per your given code sample it seems that you are sending picture
from your front-end
application (angular) by type="file" name="Image" id="Image"
which seems good. Unfortunately, your asp.net core
backend
has no capabilities to receive that picture at this moment. So it would be best if you had a few modifications to your existing code as below.
Modify Controller Definition :
[HttpPost]
public async Task<IActionResult> CreateProduct(CreateProductDto pro, IFormFile Image)
{
try
{
//Checking if the user uploaded the image correctly
if (Image == null || Image.Length == 0)
{
return Content("File not selected");
}
//Set the image location under WWWRoot folder. For example if you have the folder name image then you should set "image" in "FolderNameOfYourWWWRoot"
var path = Path.Combine(_environment.WebRootPath, "FolderNameOfYourWWWRoot", Image.FileName);
//Saving the image in that folder
using (FileStream stream = new FileStream(path, FileMode.Create))
{
await Image.CopyToAsync(stream);
stream.Close();
}
//Setting Image name in your product DTO
//If you want to save image name then do like this But if you want to save image location then write assign the path
pro.ImageUrl = Image.FileName;
var productEntity = _mapper.Map<Product>(pro);
var newProduct = _SqlService.AddProduct(productEntity);
var productForReturn = _mapper.Map<ProductDto>(newProduct);
return CreatedAtRoute("GetProduct", new { id = productForReturn.ProId },
productForReturn);
}
catch (Exception ex)
{
return StatusCode(500, $"Internal server error: {ex}");
}
}
Explanation:
Firstly
, your controller signature was like ActionResult<ProductDto>
seems you are trying to return your product dto
after a successful response. But async Task<IActionResult>
can also do the same. So I have modified the signature.
Secondly
, your existing controller parameter was like CreateProduct(CreateProductDto pro)
which cannot handle the uploaded picture from your front-end
application request. So to handle that you should have this modification CreateProduct(CreateProductDto pro, IFormFile Image)
now your controller will understand a picture property
would be sent from your front-end
application by name of name="Image"
.
Output:
Once you upload the picture it will save the information into the database
as below.
Note:
When you would save ImageName
it will save into the database as ImageName
on the other hand when you would save the path
it will save as ImageLocation
fashion.
CodePudding user response:
From Angular your sending a file while your modal is waiting for an ImageUrl. The missing part here is a an image saving service (Intercepts the file from Angular, save it in the database, then return an URL (/yourServer/yourProject/pictures/picture01.jpeg). Then you set the returned URL to th DTO object and you persist it). One of the good ways to save pictures from Angular to the Database is to use Base64 converting like this example: https://www.thecodehubs.com/generate-base64-string-and-display-image-in-angular-12/