1

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 -> Artists
        [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(); // add return body?
        }

CreateArtost in inMemRepository

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

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("/events/{eventId}/program/artists/{artistId}/image")]
    public async Task<ActionResult<UpdateImageInEventArtistDto>> 
    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 => 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 => 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;
        }
vvvvv
  • 25,404
  • 19
  • 49
  • 81
  • 1
    Take a look at ASP.NET's [IFormFile](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iformfile?view=aspnetcore-7.0), you should be able to simply attach the image as form data with content type `image/png` (or whatever the file format for your image is) – MindSwipe Jan 06 '23 at 07:03

1 Answers1

1

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

[HttpPost]
[Route("api/image/upload")]
public async Task<IActionResult> 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.

Emin Niftiyev
  • 197
  • 1
  • 13
  • Thank you so much! I will look into this and do some testing! How do i sore this in the object? As an array? – Magnus Pladsen Jan 06 '23 at 07:56
  • 1
    You can convert Bas64 string like this `Convert.ToBase64String(byteArrayImage)`. Then get base64 website and paste your string. If you get own image. Your code run perfectly. Base64Encoder https://www.base64encode.org/ If is useFul Please Mark as UseFul – Emin Niftiyev Jan 06 '23 at 08:00
  • Did you see my update? :) I posted it now – Magnus Pladsen Jan 06 '23 at 08:59
  • 1
    IFormFile is not string or path. It is special File format. Thats why you get error. `UpdateImageInEventArtistAsync in InMemRepository` you equel to image and IFormFile is not correct. – Emin Niftiyev Jan 06 '23 at 09:56
  • 1
    That Time. why Your artist entity have image property in string format? – Emin Niftiyev Jan 06 '23 at 10:00
  • Okay, so if i change "IFormFile file" to "string image" on UpdateImageInEventArtistAsync in InMemRepository it will work? – Magnus Pladsen Jan 06 '23 at 10:01
  • The image property was string because that is how i used it before. How would you do it? – Magnus Pladsen Jan 06 '23 at 10:02
  • 1
    It depend your reason. If you have File Server, that time enough save FilePath. if you dont have, that time You save image like Base64 or ByteArray. Base64Format is old tech. is easy but not practice. Best way to save in your db as BYTEARRAY – Emin Niftiyev Jan 06 '23 at 10:08