簡體   English   中英

如何在 ASP.Net 核心代碼中上傳圖像第一種方法並使用郵遞員發送圖像

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

在此處輸入圖片說明 這是我的模型課

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


}

這是我用於發布請求的控制器類我創建了一個 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);


    }

這是我的數據庫上下文

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

我只需要使用郵遞員進行測試並將其與角度結合起來。 有人能幫我嗎? 當我通過郵遞員發送圖像時,出現此錯誤請求實體的媒體類型不支持服務器或資源不支持。

那是因為您在控制器中使用了[ApiController] ,它默認允許來自 body 的數據。 因此,您需要使用[FromForm]屬性來指定源,如下所示:

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

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

對不起,我在代碼中的西班牙語。

這就是我在 Base64 中上傳文件然后將文件復制到目錄的方式。 我使用頁面http://base64.guru/converter/encode/file將對象ArchivoAnexoUploadDto以將文件轉換為 base64。

我希望這段代碼摘錄對你有用

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

    }

我編寫了一個對象列表 < ArchivoAnexoUploadDto > 並且該服務將基數 64 轉換為 Bytes 數組。

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

Service recibe the Array 和PrepareFileList返回相同的數據,但數組具有 IFormFile 而不是 Base64 字符串。

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

ArchivoAnexoCreateDto是具有 IFormFile 屬性的 Dto,用於將文件復制到目錄。

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.");
        }
    }

這是驗證的條件(僅用於解釋)我之所以這樣做是因為企業配置了擴展列表、文件大小限制等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM