.net core api 圖片上傳與加載

 

關於.net core API 圖片上傳與加載 文件夾

[TOC]html

1.上傳圖片

1.配置Swagger 與文件夾、接口添加
1.創建.net core api 項目 下載 NuGet 包 Swashbuckle.AspNetCore 
2.進入 starup 中 ConfigureServices 配置 ,添加以下代碼
3.點擊項目右鍵屬性->生成->XML 文檔文件 ✔ 上,接着在取消顯示警告添加1591->保存
services.AddSwaggerGen(s =>

           {

               s.SwaggerDoc("v1", new Info

               {

                   Title = "圖片上傳",

                   Description = "圖片上傳測試",

                   Version = "v1"

               });



               #region XML備註



               var basePath = Path.GetDirectoryName(AppContext.BaseDirectory);

               var imagePath = Path.Combine(basePath, "ImageDemo.xml");

               s.IncludeXmlComments(imagePath,true);



               #endregion

           });
4.進入 starup 中 Configure 配置 ,添加以下代碼
app.UseSwagger();
app.UseSwaggerUI(s => s.SwaggerEndpoint("/swagger/v1/swagger.json", "v1版本"));
5.點擊 Properties 編輯爲下面
{
  /*"$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:59623",
      "sslPort": 44385
    }
  },*/
  "profiles": {/*
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "api/values",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },*/
    "ImageDemo": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
6.運行項目,即可以看到結果,以上 Swagger 配置完畢
2.編寫接口
  1. 添加三個文件夾前端

    • Images 存儲圖片
      • 裏面在設置一個名稱爲 6 的文件夾
    • IRepositories 接口文件夾
      • 新建接口類 IImagesResource
    • Repositories 實現類文件夾
      • 新建實現類 ImagesResource
  2. 實現類代碼git

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace ImageDemo.IRepositories
{
    public interface IImagesResource
    {
        /// <summary>
        /// 加載圖片
        /// </summary>
        /// <param name="path">路徑</param>
        /// <param name="name">圖片名</param>
        /// <returns></returns>
        FileContentResult LoadingPhoto(string path, string name);

        /// <summary>
        /// 上傳圖片
        /// </summary>
        /// <param name="formFile">圖片</param>
        /// <param name="path">路徑</param>
        /// <param name="name">圖片名字</param>
        /// <returns></returns>
        CustomStatusCode UpLoadPhoto(IFormFile formFile, string path);
    }
}

2.實現圖片上傳

先上代碼
實現類總代碼github

using System;
using System.IO;
using System.Linq;
using ImageDemo.IRepositories;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace ImageDemo.Repositories
{
    public class ImagesResource:ControllerBase,IImagesResource
    {
        public static string[] LimitPictureType = {".PNG", ".JPG", ".JPEG", ".BMP", ".ICO"};

        /// <summary>
        /// 加載圖片
        /// </summary>
        /// <param name="path"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public FileContentResult LoadingPhoto(string path, string name)
        {
            path = Directory.GetCurrentDirectory() + path + name + ".jpeg";
            FileInfo fi=new FileInfo(path);
            if (!fi.Exists)
            {
                return null;
            }

            FileStream fs = fi.OpenRead();
            byte[] buffer=new byte[fi.Length];
            //讀取圖片字節流
            //從流中讀取一個字節塊,並在給定的緩衝區中寫入數據。
            fs.Read(buffer, 0, Convert.ToInt32(fi.Length));
            var resource = File(buffer, "image/jpeg");
            fs.Close();
            return resource;
        }

        /// <summary>
        /// 上傳圖片
        /// </summary>
        /// <param name="formFile"></param>
        /// <param name="path">路勁</param>
        /// <returns></returns>
        public CustomStatusCode UpLoadPhoto(IFormFile formFile, string path)
        {
            CustomStatusCode code;
            var currentPictureWithoutExtension = Path.GetFileNameWithoutExtension(formFile.FileName);
            var currentPictureExtension = Path.GetExtension(formFile.FileName).ToUpper();
            path = Directory.GetCurrentDirectory() + path;
            if (LimitPictureType.Contains(currentPictureExtension))
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                string name = currentPictureWithoutExtension + ".jpeg";
                path += name;
                using (var fs=System.IO.File.Create(path))
                {
                    formFile.CopyTo(fs);
                    //Stream 都有 Flush() 方法,
                    //根據官方文檔的說法
                    //「使用此方法將全部信息從基礎緩衝區移動到其目標或清除緩衝區,或者同時執行這兩種操做」
                    fs.Flush();
                }
                code = new CustomStatusCode
                {
                    Status = "200",
                    Message = $"圖片 {name} 上傳成功"
                };
                return code;
            }
            code = new CustomStatusCode
            {
                Status = "400",
                Message = $"圖片上傳失敗,格式錯誤"
            };
            return code;
        }
    }
}

上面有個重點是實現類還繼承了 ControllerBase,而且繼承位置要在IImagesResource以前
其中 CustomStatusCode 類是信息返回類下面貼下數據庫

namespace ImageDemo
{
    public class CustomStatusCode
    {
        public object Status;
        public object Message { get; set; }
        public object Data { get; set; }
    }
}

取出裏面的上傳圖片代碼json

/// <summary>
        /// 上傳圖片
        /// </summary>
        /// <param name="formFile">圖片</param>
        /// <param name="path">路勁</param>
        /// <returns></returns>
        public CustomStatusCode UpLoadPhoto(IFormFile formFile, string path)
        {
            CustomStatusCode code;
            var currentPictureWithoutExtension = Path.GetFileNameWithoutExtension(formFile.FileName);
            var currentPictureExtension = Path.GetExtension(formFile.FileName).ToUpper();
            path = Directory.GetCurrentDirectory() + path;
            if (LimitPictureType.Contains(currentPictureExtension))
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                string name = currentPictureWithoutExtension + ".jpeg";
                path += name;
                using (var fs=System.IO.File.Create(path))
                {
                    formFile.CopyTo(fs);
                    //Stream 都有 Flush() 方法,
                    //根據官方文檔的說法
                    //「使用此方法將全部信息從基礎緩衝區移動到其目標或清除緩衝區,或者同時執行這兩種操做」
                    fs.Flush();
                }
                code = new CustomStatusCode
                {
                    Status = "200",
                    Message = $"圖片 {name} 上傳成功"
                };
                return code;
            }
            code = new CustomStatusCode
            {
                Status = "400",
                Message = $"圖片上傳失敗,格式錯誤"
            };
            return code;
        }

解釋階段windows

  1. IFormFile
    • 是上傳的文件
  2. var currentPictureWithoutExtension = Path.GetFileNameWithoutExtension(formFile.FileName);
    • 獲取沒有後綴擴展名的文件名,如傳過來的是 image.png,通過上面 currentPictureWithoutExtension = image
  3. var currentPictureExtension = Path.GetExtension(formFile.FileName).ToUpper();
    • 獲得 formFile 的擴展名並將其
  4. path = Directory.GetCurrentDirectory() + path;
    • Directory.GetCurrentDirectory()獲得當前程序的路勁,也就是和 Starup.cs 文件同等級的存在
  5. string name = currentPictureWithoutExtension + 「.jpeg」;
    • 這段代碼是爲了保存圖片將後綴名統一,由於提取圖片須要後綴名,之後提取圖片方便點,這是個很次的寫法,當時沒想到其餘的方法,這個方法不怎麼可取後面我會改,先留個坑
  6. fs.Flush();
    • 這個解釋是看網上的說明
    • Stream 都有 Flush() 方法,根據官方文檔的說法「使用此方法將全部信息從基礎緩衝區移動到其目標或清除緩衝區,或者同時執行這兩種操做」api

3.加載圖片

貼代碼app

/// <summary>
       /// 加載圖片
       /// </summary>
       /// <param name="path"></param>
       /// <param name="name"></param>
       /// <returns></returns>
       public FileContentResult LoadingPhoto(string path, string name)
       {
           path = Directory.GetCurrentDirectory() + path + name + ".jpeg";
           FileInfo fi=new FileInfo(path);
           if (!fi.Exists)
           {
               return null;
           }

           FileStream fs = fi.OpenRead();
           byte[] buffer=new byte[fi.Length];
           //讀取圖片字節流
           //從流中讀取一個字節塊,並在給定的緩衝區中寫入數據。
           fs.Read(buffer, 0, Convert.ToInt32(fi.Length));
           var resource = File(buffer, "image/jpeg");
           fs.Close();
           return resource;
       }
  1. File(buffer, 「image/jpeg」)
    • 這個方法繼承自 ControllerBase 並非來自 using System.IO
    • 至於怎樣用 using System.IO; 把圖片取出來…我還沒學,望大佬教教

4.Controller 控制器

貼代碼測試

 

using ImageDemo.Db;
using ImageDemo.IRepositories;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.IO;

namespace ImageDemo.Controllers
{
[Route(「api/[controller]」)]
[ApiController]
public class ValuesController : ControllerBase
{
#region Inistial

private readonly DbContext _dbContext;
    private readonly IImagesResource _imagesResource;

    private readonly ILogger<ValuesController> _logger;

    public ValuesController(
        ILogger<ValuesController> logger,
        DbContext dbContext,
        IImagesResource imagesResource)
    {
        _logger = logger;
        _dbContext = dbContext;
        _imagesResource = imagesResource;
    }

    #endregion

    /// <summary>
    /// 批量上傳圖片
    /// </summary>
    /// <param name="file"></param>
    /// <param name="formCollection"></param>
    [HttpPost]
    public IActionResult Post([FromForm] IFormFileCollection formCollection)
    {
        IList<CustomStatusCode> code=new List<CustomStatusCode>();
            if (formCollection.Count > 0)
            foreach (IFormFile file in formCollection)
            {
                var currentCode=_imagesResource.UpLoadPhoto(file, @"\images\6\");
                code.Add(currentCode);
            }

            return StatusCode(200,code);
    }

    /// <summary>
    /// 獲取圖片
    /// </summary>
    /// <param name="imgName"></param>
    /// <returns></returns>
    [HttpGet]
    public IActionResult Get(string imgName)
    {
        var image = _imagesResource.LoadingPhoto("\\Images\\6\\", imgName);
        if (image == null)
        {
            _logger.LogInformation($"圖片 {imgName} 不存在");
            var code = new CustomStatusCode
            {
                Status = "404",
                Message = $"圖片 {imgName} 加載不存在"
            };
            return StatusCode(404, code);
        }

        return image;

        #region MyRegion

        /*string[] LimitPictureType =
            {".PNG", ".JPG", ".JPEG", ".BMP", ".GIF", ".ICO"};
        GetFileName(di);
        

        

        
        string path = Directory.GetCurrentDirectory()+ $@"\Images\6\{imgName}"+".jpeg";

        FileInfo fi = new FileInfo(path);
        FileStream fs = fi.OpenRead(); ;
        byte[] buffer = new byte[fi.Length];
        //讀取圖片字節流
        fs.Read(buffer, 0, Convert.ToInt32(fi.Length));
        var response = File(buffer, "image/jpeg");
        fs.Close();
        return response;
        */

        #endregion
    }

    private static IList<string> path = new List<string>(); //保存你圖片名稱
    DirectoryInfo di = new DirectoryInfo(Directory.GetCurrentDirectory()+@"\Images\6\");

    /// <summary>
    /// 加載目錄內文件夾名
    /// </summary>
    /// <param name="info"></param>
    public static void GetFileName(DirectoryInfo info)
    {
        //獲取該路徑下的全部文件的列表
        FileInfo[] fileInfo = info.GetFiles();

        //開始獲得圖片名稱
        foreach (FileInfo subinfo in fileInfo)
        {
            //判斷擴展名是否相同
            // if (subinfo.Extension == extension)
            // {
            string strname = subinfo.Name; //獲取文件名稱

            path.Add(strname); //把文件名稱保存在泛型集合中
            // }
        }
    }
}

}


5.想法,問題與 GitHub

問題:

  1. 上傳圖片能夠多張上傳,加載圖片的方法原本也想多張加載,當時多張的話,圖片就會變成字符串的形式,不知爲什麼,求解
  2. 若是不用 ControllerBse 中的 File 那麼該如何向頁面傳遞圖片

有兩個想法,朋友提的:

  1. 那個加載圖片直接創建一個html網頁,將圖片放進去,前端這樣能夠訪問圖片,應該可行,不知效率怎樣
  2. 那個改後綴的實屬下策,能夠用創建數據庫,兩列,一列存儲圖片名,一列存儲圖片後綴,存儲的時候能夠將圖片的名字改下,若是是用戶頭像,能夠改成用戶 Id 這樣數字就惟一了
相關文章
相關標籤/搜索