.NET 6 API – 从前端上传图像至数据库

huangapple go评论90阅读模式
英文:

.NET 6 API - Upload image from frontend to database

问题

我正在作为初级开发人员参与我的第一个项目,但我也被分配了创建后端 API 的任务。因此,这是我第一次接触后端,我几乎不了解 C# 或 .NET。

前端:Nextjs,typescript
后端:.NET 6,C#

问题:
用户需要能够上传图像到艺术家对象。目前,我只是使用一个表示图像在前端存储路径的字符串。

我将找出如何在前端接收图像,并在 API 中创建一个端点来上传图像。

我想要问的问题是如何在 .NET 中接收和存储图像?

艺术家实体:

namespace BookingAPI.Entities
{
    public class Artist
    {
        public string Id { get; set; }
        public string Name { get; set; } = null!;
        public string Description { get; set; }
        public string? Image { get; set; }
    }
}

Controller 中的 CreateArtist:

// POST /events/{eventId}/program/artists
// 在 Program 中创建新的艺术家
[HttpPost]
[Route("/events/{eventId}/program/artists")]
public async Task<ActionResult<EventArtistDto>> CreateEventArtistAsync(string eventId, CreateEventArtistDto createEventArtistDto)
{
    Artist artist = new()
    {
        Id = Guid.NewGuid().ToString(),
        Name = createEventArtistDto.Name,
        Description = createEventArtistDto.Description,
        Image = createEventArtistDto.Image,
    };

    await repository.CreateEventArtistAsync(eventId, artist);

    return artist.AsDto(); // 是否需要添加返回内容?
}

InMemRepository 中的 CreateArtist:

public async Task CreateEventArtistAsync(string eventId, Artist artist)
{
    var eventIndex = events.FindIndex(existingEvent => existingEvent.Id == eventId);

    var existingEvent = events[eventIndex];

    var artists = existingEvent.EventProgram.Artists;

    artists.Add(artist);

    await Task.CompletedTask;
}

请让我知道是否需要上传更多代码。

我真的不确定如何开始这段代码,当然,我同时也在搜索,但我想自己提出问题,以便可能可以正确学习这个过程。

更新:

在阅读 @EminNiftiyev 的答案后,我尝试了以下代码,但遇到了错误:

Controller: "隐式类型的变量必须初始化"

InMemRepository: "无法隐式转换类型 'Microsoft.AspNetCore.Http.IFormFile' 为 'string'"

我不完全理解我在这里做什么。

Controller 中的 UpdateImageInEventArtistAsync:

// PUT /events/{eventId}/program/artists/{artistId}/image
// 更新艺术家的图像
[HttpPost]
[Route("/events/{eventId}/program/artists/{artistId}/image")]
public async Task<ActionResult<UpdateImageInEventArtistDto>> 
UpdateImageInEventArtistAsync(string eventId, string artistId, 
UpdateImageInEventArtistDto updateImageInEventArtistDto, 
[FromForm] IFormFile file)
{
    // 从事件获取节目
    var program = await repository.GetEventProgramAsync(eventId);

    var existingArtist = program.Artists.Where(artist => artist.Id == artistId).SingleOrDefault();

    if (existingArtist is null)
    {
        return NotFound();
    }

    var byteArrayImage;
    using (var stream = new MemoryStream())
    {
        await file.CopyToAsync(stream);
        byteArrayImage = stream.ToArray();
    }
    existingArtist.Image = Convert.ToBase64String(byteArrayImage);

    /* await repository.UpdateEventArtistAsync(eventId, artistId, existingArtist); */
    await repository.UpdateImageInEventArtistAsync(eventId, artistId, byteArrayImage);

    return NoContent();
}

InMemRepository 中的 UpdateImageInEventArtistAsync:

public async Task UpdateImageInEventArtistAsync(string eventId, string artistId, IFormFile file)
{
    var eventIndex = events.FindIndex(existingEvent => existingEvent.Id == eventId);

    var existingEvent = events[eventIndex];

    var artists = existingEvent.EventProgram.Artists;

    var existingArtist = artists.Where(artist => artist.Id == artistId).SingleOrDefault();

    existingArtist.Image = file;

    await Task.CompletedTask;
}
英文:

I am working on my first project as a junior developer, but i also got the task of creating the backend API. This is therefore my first time touching any backend so i almost dont know any c# or .NET.

Frontend: Nextjs, typescript
Backend: .NET 6, c#

The problem:
The users need to be able to upload an image to an artist object. As of now i am only using a string that represents the path where the image is stored in the frontend.

I will figure out how i will recieve the image in the frontend, and i will create an endpoint in the API where i can PUT the image.

The question im trying to ask is how do i do the recieving and storing of the image in the .NET?

Artist entity:

namespace BookingAPI.Entities
{
    public class Artist
    {
        public string Id { get; set; }
        public string Name { get; set; } = null!;
        public string Description { get; set; }
        public string? Image { get; set; }
    }
}

CreateArtist in Controller

// POST /events/{eventId}/program/artists
        // Create new artist in Program -&gt; Artists
        [HttpPost]
        [Route(&quot;/events/{eventId}/program/artists&quot;)]
        public async Task&lt;ActionResult&lt;EventArtistDto&gt;&gt; CreateEventArtistAsync(string eventId, CreateEventArtistDto createEventArtistDto)
        {
            Artist artist = new()
            {
                Id = Guid.NewGuid().ToString(),
                Name = createEventArtistDto.Name,
                Description = createEventArtistDto.Description,
                Image = createEventArtistDto.Image,
            };

            await repository.CreateEventArtistAsync(eventId, artist);

            return artist.AsDto(); // add return body?
        }

CreateArtost in inMemRepository

        public async Task CreateEventArtistAsync(string eventId, Artist artist)
        {
            var eventIndex = events.FindIndex(existingEvent =&gt; existingEvent.Id == eventId);

            var existingEvent = events[eventIndex];

            var artists = existingEvent.EventProgram.Artists;

            artists.Add(artist);

            await Task.CompletedTask;
        }

Please let me know if i should upload more of the code.

Im really not sure even how to start this code, i am of course googling this at the same time, but though i would make my own question as well so that maybe i could learn this the proper way.

UPDATE:

After reading @EminNiftiyev answer i tried this,
but i get errors:

Controller: "Implicitly-typed variables must be initialized"

InMemRepository: "Cannot implicitly convert type 'Microsoft.AspNetCore.Http.IFormFile' to 'string'"

I dont fully understand what i am doing here.

UpdateImageInEventArtistAsync in Controller

//PUT /events/{eventId}/program/artists/{artistId}/image
    // Update the Image in the Artist
    [HttpPost]
    [Route(&quot;/events/{eventId}/program/artists/{artistId}/image&quot;)]
    public async Task&lt;ActionResult&lt;UpdateImageInEventArtistDto&gt;&gt; 
    UpdateImageInEventArtistAsync(string eventId, string artistId, 
    UpdateImageInEventArtistDto updateImageInEventArtistDto, 
    [FromForm] IFormFile file)
    {
        // Get Program from Event
            var program = await repository.GetEventProgramAsync(eventId);

            var existingArtist = program.Artists.Where(artist =&gt; artist.Id == artistId).SingleOrDefault();

            if (existingArtist is null)
            {
                return NotFound();
            }

            var byteArrayImage;
            using (var stream = new MemoryStream())
            {
                await file.CopyToAsync(stream);
                byteArrayImage = stream.ToArray();
            }
            existingArtist.Image = Convert.ToBase64String(byteArrayImage);



            /* await repository.UpdateEventArtistAsync(eventId, artistId, existingArtist); */
            await repository.UpdateImageInEventArtistAsync(eventId, artistId, byteArrayImage);

            return NoContent();
    }

UpdateImageInEventArtistAsync in InMemRepository

public async Task UpdateImageInEventArtistAsync(string eventId, string artistId, IFormFile file)
        {
            var eventIndex = events.FindIndex(existingEvent =&gt; existingEvent.Id == eventId);

            var existingEvent = events[eventIndex];

            var artists = existingEvent.EventProgram.Artists;

            var existingArtist = artists.Where(artist =&gt; artist.Id == artistId).SingleOrDefault();

            
            
            existingArtist.Image = file;

            await Task.CompletedTask;
        }

答案1

得分: 1

首先,您创建了用于上传图像的端点。那时,完美的选择是使用 IFormFile。代码如下:

[HttpPost]
[Route("api/image/upload")]
public async Task<IActionResult> UploadImage([FromForm] IFormFile file)
{
}

然后,您可以获取图像的字节数组格式。为此,您应该使用流(Stream):

var byteArrayImage;
using (var stream = new MemoryStream())
{
   await file.CopyToAsync(stream);
   byteArrayImage = stream.ToArray();
}

这样,您现在可以获取图像的字节数组格式了。最后,您可以将其插入到数据库或其他数据源中。

这是另一种完美的实践方式。

英文:

First you create endPoint for Upload Image. That time perfectly choice is use IFormFile. Code like this

[HttpPost]
[Route(&quot;api/image/upload&quot;)]
public async Task&lt;IActionResult&gt; UploadImage([FromForm] IFormFile file)
{
}

Then you get image like byteArray format. For this you should use Stream

var byteArrayImage;
using (var stream = new MemoryStream())
{
   await file.CopyToAsync(stream);
   byteArrayimage = stream.ToArray();
}

Here we go. Now yo can get Image like ByteArray format. And Finally you can insert to Database or another source.

That's perfect practice from another way.

huangapple
  • 本文由 发表于 2023年1月6日 14:56:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75027871.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定