c# - 如何在 ASP.net Core Web API 和 Angular 13 中上传图片

标签 c# angular asp.net-core asp.net-core-webapi

我需要将图片保存在文件目录中。数据已保存在数据库中。但我想保存图像。我对此没有正确的理解

Angular 形式

<form [formGroup]="myForm" (ngSubmit)="submit()">
            <mat-card>
                <h2 class="fw-bold text-center">Product Management</h2>
                <label class="fw-bold" for="">Product Name</label>
                <input type="text" name="name" id="name" formControlName="ProductName" class="form-control">

                <input type="text" name="description" id="description" placeholder="Product Description" class="form-control mt-3 mb-2" formControlName="ProductDescription">
                <input type="text" name="price" id="price" placeholder="Product Price" class="form-control mt-3 mb-2"  formControlName="price">
                <input type="text" name="created" id="created" placeholder="Product created" class="form-control mt-3 mb-2"  formControlName="created">
                <input type="text" name="cat" id="cat" placeholder="Product created" class="form-control mt-3 mb-2"  formControlName="ProductCatID">

                <input type="file" name="Image" id="Image" class="form-control mt-3 mb-2" (change)="onFileChange($event)" formControlName="ImageUrl">
                <img [src]="imageSrc" *ngIf="imageSrc" style="height: 300px; width:500px">

                <button type="submit" class="btn btn-primary btn-block mt-3">Submit</button>
            </mat-card>
        </form>

Angular TS 文件

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.');
})

}

我认为 Angular 部分没有问题。

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}");
        }
        
    }

这是模型类

 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; }
}

这是创建 Dto 类

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; }
    
}

这是我的 SQL 服务代码

public Product AddProduct(Product product)
    {
        _context.Products.Add(product);
        _context.SaveChanges();

        return _context.Products.Find(product.ProId);
    }

最佳答案

“我需要将图片保存在文件目录中。数据已经保存在数据库中。但是我想保存图像。我对此没有正确的理解”

Well, let's assume we want to upload product image in the image folder under wwwroot within our application. Just like the image below:

enter image description here

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 or image path location into the database which is the best practice so far.

您当前的情况:

根据您给定的代码示例,您似乎正在发送 picture来自您的front-end应用程序( Angular )type="file" name="Image" id="Image"这看起来不错。不幸的是,你的asp.net core backend目前无法接收该图片。因此,最好对现有代码进行一些修改,如下所示。

修改 Controller 定义:

        [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}");
            }

        }

说明:

<强> Firstly ,你的 Controller 签名就像 ActionResult<ProductDto>似乎您正在尝试返回您的 product dto成功回复后。但是async Task<IActionResult>也可以做同样的事情。所以我修改了签名。

<强> Secondly ,您现有的 Controller 参数类似于 CreateProduct(CreateProductDto pro)它无法处理您 front-end 上传的图片申请请求。因此,要处理这个问题,您应该进行此修改 CreateProduct(CreateProductDto pro, IFormFile Image)现在你的 Controller 将理解 picture property将从您的 front-end 发送名为 name="Image" 的申请.

输出:

上传图片后,它会将信息保存到database中如下。

enter image description here

注意:

当您保存ImageName时它将保存到数据库中 ImageName另一方面,当您保存 path 时它将另存为ImageLocation时尚。

关于c# - 如何在 ASP.net Core Web API 和 Angular 13 中上传图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72475709/

相关文章:

c# - 什么会阻止在 C# 语言中向枚举添加属性?

html - Angular 2使整行可点击

javascript - 无法运行 Node.js 应用程序,因为 : 'Failed to lookup view "error"in views directory'

asp.net-core - 使用 Blazor WebAssembly 设置日志记录

c# - .Net Core Web API,如果角色或策略匹配则授权操作

c# - 缺少公开可见类型或成员的 XML 注释

c# - 处理由 C# 生成的 html 中的嵌套引号

c# - 使用 explorer.exe 打开应用程序,但添加了设置

angular - 子路由中的参数

c# - 无法调试 Blazor wasm