最近的項目里有上傳圖片的功能,當然這個功能在項目里是必須要有的,那么目前這個項目是使用完全的前后端分離,在選擇文件上傳的組件中還是選擇了全面支持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() <= 0) { 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) <= 1024 * 1024 * 4) { 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="52" 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; } }