[TOC]
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 配置完毕
添加三个文件夹
实现类代码
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace ImageDemo.IRepositories
{
public interface IImagesResource
{
///
/// 加载图片
///
/// 路径
/// 图片名
///
FileContentResult LoadingPhoto(string path, string name);
///
/// 上传图片
///
/// 图片
/// 路径
/// 图片名字
///
CustomStatusCode UpLoadPhoto(IFormFile formFile, string path);
}
}
先上代码
实现类总代码
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"};
///
/// 加载图片
///
///
///
///
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;
}
///
/// 上传图片
///
///
/// 路劲
///
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; }
}
}
取出里面的上传图片代码
///
/// 上传图片
///
/// 图片
/// 路劲
///
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;
}
解释阶段
Stream 都有 Flush() 方法,根据官方文档的说法“使用此方法将所有信息从基础缓冲区移动到其目标或清除缓冲区,或者同时执行这两种操作”
贴代码
///
/// 加载图片
///
///
///
///
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;
}
贴代码
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 _logger;
public ValuesController(
ILogger logger,
DbContext dbContext,
IImagesResource imagesResource)
{
_logger = logger;
_dbContext = dbContext;
_imagesResource = imagesResource;
}
#endregion
///
/// 批量上传图片
///
///
///
[HttpPost]
public IActionResult Post([FromForm] IFormFileCollection formCollection)
{
IList code=new List();
if (formCollection.Count > 0)
foreach (IFormFile file in formCollection)
{
var currentCode=_imagesResource.UpLoadPhoto(file, @"\images\6\");
code.Add(currentCode);
}
return StatusCode(200,code);
}
///
/// 获取图片
///
///
///
[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 path = new List(); //保存你图片名称
DirectoryInfo di = new DirectoryInfo(Directory.GetCurrentDirectory()+@"\Images\6\");
///
/// 加载目录内文件夹名
///
///
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); //把文件名称保存在泛型集合中
// }
}
}
}
}
问题:
- 上传图片可以多张上传,加载图片的方法本来也想多张加载,当时多张的话,图片就会变成字符串的形式,不知为何,求解
- 如果不用 ControllerBse 中的 File 那么该如何向页面传递图片
有两个想法,朋友提的:
- 那个加载图片直接建立一个html网页,将图片放进去,前端这样可以访问图片,应该可行,不知效率怎样
- 那个改后缀的实属下策,可以用建立数据库,两列,一列存储图片名,一列存储图片后缀,存储的时候可以将图片的名字改下,如果是用户头像,可以改为用户 Id 这样数字就唯一了