首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ASP.Net核心代码中上传图片并使用post man发送图片

如何在ASP.Net核心代码中上传图片并使用post man发送图片
EN

Stack Overflow用户
提问于 2021-10-08 05:13:59
回答 2查看 69关注 0票数 1

这是我的模型类

代码语言:javascript
复制
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; }


}

这是我的post请求的控制器类,我创建了一个wwwroot文件夹来保存图像

代码语言:javascript
复制
[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);


    }

这是我的数据库上下文

代码语言:javascript
复制
 public DbSet<ImageModel> Images { get; set; }

我只需要使用postman进行测试,并将其与angular结合使用。有人能帮我吗?当我通过postman发送图像时,我得到这个错误,请求实体有一个不支持服务器或资源不支持的媒体类型。

EN

回答 2

Stack Overflow用户

发布于 2021-10-11 02:41:18

这是因为您在控制器中使用了[ApiController],默认情况下,它允许来自body的数据。因此,您需要使用[FromForm]属性来指定源代码,如下所示:

代码语言:javascript
复制
[HttpPost]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageName")][FromForm] ImageModel imageModel)
{
    //..
    return View(imageModel);
}

此外,如果您使用[Bind("ImageId,Title,ImageName")],ImageFile将无法绑定到模型。

票数 0
EN

Stack Overflow用户

发布于 2021-10-13 21:50:00

很抱歉我在代码中使用了西班牙语。

这就是我在Base64中上传文件,然后将文件复制到目录中的方法。我使用页面http://base64.guru/converter/encode/file将文件转换为base64来生成对象ArchivoAnexoUploadDto

我希望这段代码的摘录对你有用。

1-控制器

代码语言:javascript
复制
[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);
        }

    }

我收到一个对象列表< ArchivoAnexoUploadDto >,服务将基数64转换为字节数组。

2-服务

代码语言:javascript
复制
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 = "" };
    }

服务接收数组和PrepareFileList返回相同的数据,但数组使用IFormFile而不是Base64字符串。

3- Dtos

代码语言:javascript
复制
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是接收base64和文件名的Dto。

ArchivoAnexoCreateDto是具有IFormFile属性的Dto,用于将文件复制到目录。

4-验证要复制到目录的IFormFile

代码语言:javascript
复制
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.");
        }
    }

这是验证的条件(仅用于解释)我之所以这样做,是因为业务配置了一个扩展名列表,文件的大小限制等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69490802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档