Home > Mobile >  How to upload image in ASP.Net core code first approach and send image using post man
How to upload image in ASP.Net core code first approach and send image using post man

Time:10-15

enter image description hereThis is my model class

public class ImageModel
{
    [Key]
    public int ImageId { get; set; }

    [Column(TypeName = "nvarchar(50)")]
    public string Title { get; set; }

    [Column(TypeName = "nvarchar(100)")]
    [DisplayName("Image Name")]
    public string ImageName { get; set; }

    [NotMapped]
    [DisplayName("Upload File")]
    public IFormFile ImageFile { get; set; }


}

This is my controller class for post request And I create a wwwroot folder to save Image

[Route("api/[Controller]")]
[ApiController]
public class ImageController : Controller
{
    private readonly Databasecontext _context;
    private readonly IWebHostEnvironment _hostEnvironment;



    

    public ImageController(Databasecontext context, IWebHostEnvironment hostEnvironment)
    {
        _context = context;
        this._hostEnvironment = hostEnvironment;
    }

    // GET: Image
    public async Task<IActionResult> Index()
    {
        return View(await _context.Images.ToListAsync());
    }

    // GET: Image/Create
    public IActionResult Create()
    {
        return View();
    }

    // POST: Image/Create

    [HttpPost]
    
    public async Task<IActionResult> Create([Bind("ImageId,Title,ImageName")] ImageModel imageModel)
    {
        if (ModelState.IsValid)
        {
            //Save image to wwwroot/image
            string wwwRootPath = _hostEnvironment.WebRootPath;
            string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
            string extension = Path.GetExtension(imageModel.ImageFile.FileName);
            imageModel.ImageName = fileName = fileName   DateTime.Now.ToString("yymmssfff")   extension;
            string path = Path.Combine(wwwRootPath   "/Image/", fileName);
            using (var fileStream = new FileStream(path, FileMode.Create))
            {
                await imageModel.ImageFile.CopyToAsync(fileStream);
            }
            //Insert record
            _context.Add(imageModel);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(imageModel);


    }

This is my DB context

 public DbSet<ImageModel> Images { get; set; }

I just need to test this using postman and combine it with angular. Can someone help me? when I send an image through postman I get this error The request entity has a media type that doesn't support server or resource does not support.

CodePudding user response:

That is because you use [ApiController] in your controller, it allows data from body by default. So you need specific the source by using [FromForm] attribute like below:

[HttpPost]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageName")][FromForm] ImageModel imageModel)
{
    //..
    return View(imageModel);
}

Besides, if you use [Bind("ImageId,Title,ImageName")], ImageFile cannot be binded to the model.

CodePudding user response:

Sorry for my Spanish in the code.

This is how i upload the file in Base64 and then copy the file to a Directory. I Pupulate the Object ArchivoAnexoUploadDto using a page http://base64.guru/converter/encode/file for convert a file to a base64.

I Hope tha this extract of the code will be usefull for you

1 - Controller

[HttpPost("UploadFileList")]
    public async Task<IActionResult> UploadFileList(List<ArchivoAnexoUploadDto> fileList)
    {
        IOperationResult<object> operationResult = null;
        try
        {
            operationResult = await _fileService.UploadFileList(fileList);

            if (!operationResult.Success)
            {
                return BadRequest(operationResult.ErrorMessage);
            }

            return Ok(operationResult.Entity);

        }
        catch (Exception ex)
        {
            return BadRequest(operationResult.Entity);
        }

    }

I Recibe a List of Objects < ArchivoAnexoUploadDto > and the service converts the base 64 to Bytes array.

2 - Service

public async Task<IOperationResult<object>> UploadFileList(List<ArchivoAnexoUploadDto> files)
    {
        List<ArchivoAnexoCreateDto> fileList = PrepareFileList(files);

        Response result = ValidateFiles(fileList);

        if (!result.Status)
        {
            Response responseError = new()
            {
                Status = false,
                Message = ((FormFile)result.Object).FileName,
                MessageDetail = result.Message
            };
            return OperationResult<object>.Ok(responseError);
        }

        var saveResult = await SaveFileList(fileList);

        Response respuesta = new()
        {
            Status = true,
            Message = "Los archivos fueron almacenados exitosamente.",
            MessageDetail = ""
        };
        return OperationResult<object>.Ok(respuesta);
    }


    private List<ArchivoAnexoCreateDto> PrepareFileList(List<ArchivoAnexoUploadDto> files)
    {
        List<ArchivoAnexoCreateDto> formFileList = new List<ArchivoAnexoCreateDto>();

        foreach (ArchivoAnexoUploadDto newFile in files)
        {

            byte[] fileBytes = Convert.FromBase64String(newFile.Base64);

            string filePath = Path.Combine(_fileSettings.PrincipalPath, _fileSettings.PrincipalFolderName, newFile.NombreArchivo);
            MemoryStream memoryStream = new MemoryStream();
            memoryStream.Write(fileBytes, 0, fileBytes.Length);

            FormFile fileData = new FormFile(memoryStream, 0, memoryStream.Length, newFile.NombreArchivo, newFile.NombreArchivo);

            ArchivoAnexoCreateDto fileDto = new()
            {
                FileId = 0,
                Data = fileData,
                FileName = newFile.NombreArchivo,
                Module = newFile.Modulo
            };
            formFileList.Add(fileDto);
        }

        return formFileList;
    }

    private Response ValidateFiles(List<ArchivoAnexoCreateDto> fileList)
    {
        foreach (ArchivoAnexoCreateDto fileObj in fileList)
        {
            IFormFile file = fileObj.Data;
            try
            {
                ValidateFile(file);
            }
            catch (Exception exception)
            {
                return new Response { Status = false, Message = exception.Message, Object = file };
            }
        }
        return new Response { Status = true, Message = "" };
    }

The Service recibe the Array and PrepareFileList return the same data but the array have IFormFile instead of Base64 string.

3 - Dtos

public sealed class ArchivoAnexoUploadDto
{
    public long AnexoFileId { get; set; }
    public string Base64 { get; set; }
    public string NombreArchivo { get; set; }
    public Module Modulo {get; set;}
}

public sealed class ArchivoAnexoCreateDto
{
    public long FileId { get; set; }
    public IFormFile Data { get; set; }
    public int FileTypeId { get; set; }
    public string FileName { get; set; }
    public Module Module { get; set; }
}

ArchivoAnexoUploadDto Is the Dto that recives the base64 and the name of the file.

ArchivoAnexoCreateDto Is the Dto with IFormFile property and is used to copy the file to a Directory.

4 - Validate IFormFile To Copy to Dir

private void ValidateFile(IFormFile fileToCreate)
    {
        if (fileToCreate == null)
        {
            throw new Exception("No ha enviado ningun archivo.");
        }

        IOperationResult<string> fileExtensionResult = _fileService.GetFileExtension(fileToCreate);

        if (!fileExtensionResult.Success)
        {
            throw new Exception(fileExtensionResult.ErrorMessage);
        }

        if (!_fileSettings.AllowedExtensions.Contains(fileExtensionResult.Entity))
        {
            throw new Exception("La extención del archivo no es permitida.");
        }

        IOperationResult<long> fileSizeResult = _fileService.GetFileSize(fileToCreate);

        if (!fileSizeResult.Success)
        {
            throw new Exception("Ha ocurrido un error obteniendo el tamaño del archivo.");
        }

        if (fileSizeResult.Entity > _fileSettings.MaxFileSize)
        {
            throw new Exception("El tamaño del archivo supera el limite.");
        }
    }

This are Conditions for validate (Only for explain) I Did this stuff because the business configured a list of extensions, a size limit of the files, etc.

  • Related