简体   繁体   English

如何在 ASP.Net 核心代码中上传图像第一种方法并使用邮递员发送图像

[英]How to upload image in ASP.Net core code first approach and send image using post man

在此处输入图片说明 This 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这是我用于发布请求的控制器类我创建了一个 wwwroot 文件夹来保存图像

[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.当我通过邮递员发送图像时,出现此错误请求实体的媒体类型不支持服务器或资源不支持。

That is because you use [ApiController] in your controller, it allows data from body by default.那是因为您在控制器中使用了[ApiController] ,它默认允许来自 body 的数据。 So you need specific the source by using [FromForm] attribute like below:因此,您需要使用[FromForm]属性来指定源,如下所示:

[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.此外,如果您使用[Bind("ImageId,Title,ImageName")] ,则 ImageFile 无法绑定到模型。

Sorry for my Spanish in the code.对不起,我在代码中的西班牙语。

This is how i upload the file in Base64 and then copy the file to a Directory.这就是我在 Base64 中上传文件然后将文件复制到目录的方式。 I Pupulate the Object ArchivoAnexoUploadDto using a page http://base64.guru/converter/encode/file for convert a file to a base64.我使用页面http://base64.guru/converter/encode/file将对象ArchivoAnexoUploadDto以将文件转换为 base64。

I Hope tha this extract of the code will be usefull for you我希望这段代码摘录对你有用

1 - Controller 1 - 控制器

[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.我编写了一个对象列表 < ArchivoAnexoUploadDto > 并且该服务将基数 64 转换为 Bytes 数组。

2 - Service 2 - 服务

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. Service recibe the Array 和PrepareFileList返回相同的数据,但数组具有 IFormFile 而不是 Base64 字符串。

3 - Dtos 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. ArchivoAnexoUploadDto是接收 base64 和文件名的 Dto。

ArchivoAnexoCreateDto Is the Dto with IFormFile property and is used to copy the file to a Directory. ArchivoAnexoCreateDto是具有 IFormFile 属性的 Dto,用于将文件复制到目录。

4 - Validate IFormFile To Copy to Dir 4 - 验证 IFormFile 复制到目录

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.这是验证的条件(仅用于解释)我之所以这样做是因为企业配置了扩展列表、文件大小限制等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM