最近的项目里有上传图片的功能,当然这个功能在项目里是必须要有的,那么目前这个项目是使用完全的前后端分离,在选择文件上传的组件中还是选择了全面支持Vue的IView,任何上传图片都是通过HTTP请求,服务端从request中读,那么思路有了,直接创建webapi项目吧。
一般来说,在.net core中静态文件应该放到wwwroot,在其中创建一个文件夹。
再做好跨域的东西,一般都是通过cors包。创建控制器,代码如下:
public class IndexController : ControllerBase
{
[HttpPost]
public async Task<bool> InsertPicture([FromServices]IHostingEnvironment environment)
{
var data = new PicData();
string path = string.Empty;
var files = Request.Form.Files;
if (files == null || files.Count() <= ) { data.Msg = "请选择上传的文件。"; return false; }
//格式限制
var allowType = new string[] { "image/jpg", "image/png","image/jpeg"};
if (files.Any(c => allowType.Contains(c.ContentType)))
{
if (files.Sum(c => c.Length) <= * * )
{
foreach (var file in files)
{
string strpath = Path.Combine("Upload", DateTime.Now.ToString("MMddHHmmss") + file.FileName);
path = Path.Combine(environment.WebRootPath, strpath); using (var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
await file.CopyToAsync(stream);
}
}
data.Msg = "上传成功";
return true;
}
else
{
data.Msg = "图片过大";
return false;
}
}
else {
data.Msg = "图片格式错误";
return false;
}
} }
public class PicData
{
public string Msg { get; set; }
}
代码解读:
读取wwwroot是在IHostingEnvironment对象中的,如果不通过依赖注入,就需要直接写成参数,那么file上传的参数开头都应该[FromServices]来修饰,在代码中判断了响应的文件格式、文件大小,通过file.copy就把文件保存在了服务器。
需要跨域:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddCors(options =>
{
options.AddPolicy("hehe", p => p.AllowAnyMethod()// 允许任何方法 GET,POST,PUT,DELETE, OPTIONS
.AllowAnyHeader() // 允许任何请求头
.AllowAnyOrigin() // 允许任何地址
);
});
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles(); app.UseCors("hehe");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
前台:
<template>
<div>
<Upload
multiple
type="drag"
action="http://localhost:54331/api/Index">
<div style="padding: 20px 0">
<Icon type="ios-cloud-upload" size="" style="color: #3399ff"></Icon>
<p>点击或将文件拖拽到这里上传</p>
</div>
</Upload>
</div>
</template>
<script>
export default { }
</script>
代码解读::
前台是非常简单的,在main.js中引用Iview,当然这一切的前提都需要Npm一下它.iview的这个组件,action就是你请求的方法,默认呢就是post请求。那么Iview还有别的属性,详见下方。
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
action | 上传的地址,必填 | String | - |
headers | 设置上传的请求头部 | Object | {} |
multiple | 是否支持多选文件 | Boolean | false |
data | 上传时附带的额外参数 | Object | - |
name | 上传的文件字段名 | String | file |
with-credentials | 支持发送 cookie 凭证信息 | Boolean | false |
show-upload-list | 是否显示已上传文件列表 | Boolean | true |
type | 上传控件的类型,可选值为 select (点击选择),drag (支持拖拽) |
String | select |
accept | 接受上传的文件类型 | String | - |
format | 支持的文件类型,与 accept 不同的是,format 是识别文件的后缀名,accept 为 input 标签原生的 accept 属性,会在选择文件时过滤,可以两者结合使用 | Array | [] |
max-size | 文件大小限制,单位 kb | Number | - |
效果图:
文末:
后来我们团队考虑到使用七牛这个在线储存图片站点,准备好实名的账号和sdk,获取AccessKey,SecretKey。登录七牛管理后台->个人信息->秘钥管理
那么官方给我们提供了.net core 的版本直接nuget就可以了。
代码:
/// <summary>
/// 实现将文件上传到七牛云
/// </summary>
/// <param name="stream">文件流</param>
/// <param name="fileName">文件名称</param>
/// <returns></returns>
public UploadQiNiuResult UploadImgToQiNiu(byte[] stream, string fileName)
{
Mac mac = new Mac(BlogStatic.QiNiuInfo_AccessKey, BlogStatic.QiNiuInfo_SecretKey);
// 上传策略,参见
// https://developer.qiniu.com/kodo/manual/put-policy
PutPolicy putPolicy = new PutPolicy();
// 如果需要设置为"覆盖"上传(如果云端已有同名文件则覆盖),请使用 SCOPE = "BUCKET:KEY"
// putPolicy.Scope = bucket + ":" + saveKey;
var saveKey = string.Format("BlogImg/{0}/", DateTime.Now.ToString("yyyy/MM/dd")) + fileName;
putPolicy.Scope = "blog:" + saveKey;
// 上传策略有效期(对应于生成的凭证的有效期)
putPolicy.SetExpires();
// 上传到云端多少天后自动删除该文件,如果不设置(即保持默认默认)则不删除
// putPolicy.DeleteAfterDays = 1;
string jstr = putPolicy.ToJsonString();
//获取上传凭证
var uploadToken = Auth.CreateUploadToken(mac, jstr);
UploadManager um = new UploadManager(); HttpResult result = um.UploadData(stream, saveKey, uploadToken); )
{
return JsonConvert.DeserializeObject<UploadQiNiuResult>(result.Text);
}
return null;
}
UploadQiNiuResult类
public class UploadQiNiuResult
{
public string Hash { get; set; }
public string Key { get; set; }
}