AspNetCore - MVC實戰系列目錄
. 愛留圖網站誕生
. git原始碼:https://github.com/shenniubuxing3/LovePicture.Web
. AspNetCore - MVC實戰系列(一)之Sqlserver表對映實體模型
. AspNetCore-MVC實戰系列(二)之通過繫結郵箱找回密碼
開篇嘮嗑
今天嘮嘮家常吧,最近一段時間媳婦鬧著上班,由於這裡算郊區吧所以希望我能在公司找個合適的職位,考慮到需要上下班接送孩子上學,所以工作的時間只能在早9晚5左右,不然人的精力有限會很疲倦的,因此通過各種渠道,最總她被安排到了xxx產品部門,從基本的開始學習,簡單介紹下她以前的工作主要是服裝店銷售衣服的,可以這樣說使用電腦的時間或者辦公軟體的時間很少,在家用電腦也就是看看電影,聽歌等,平常沒有涉及到各種辦公軟體,在這層前提下,這幾天在公司學習什麼業務,後臺系統,辦公通訊工具的使用竟然有打退堂鼓的意思,各種說自己不適合;想想以前在家裡教她什麼微信,支付寶轉賬等軟體的使用,很明顯就能感覺出來毛躁,愛面子。。。等;這有點像那種剛畢業又找到從來沒了解過的專業工作並且時常抱怨的朋友一樣,說什麼這不適合,哪不適合,帶的人怎麼的不好,怎麼的看不順眼;這種型別的朋友和我媳婦兒一樣一般會選擇辭職吧,這裡個人以工作6年的經驗說下個人見解:在職場上遇到困難就放棄並且幹什麼都是怕苦怕累,現在年輕還好有家裡支柱,當您成為家裡主要經濟來源的時候,您還有退路麼,您還幹輕易放棄麼;故此昨天晚上狠狠的說了媳婦一頓,哈哈真是漲了地位;
vs2017怎麼壓縮js和css檔案
同樣為了文章的乾貨性質,這裡分享下自己再開發Netcore的Mvc時候利用vs2017怎麼壓縮js和css檔案的方法,由於也netframwork的mvc不一樣(她是寫在程式碼中的)所以需要手動配置並輸入命令,壓縮主要分兩步;首先需要在web專案工程檔案中新增如下配置資訊:
1 專案中新增
2 <ItemGroup>
3 <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0-msbuild3-final" />
4 <DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.2.281" />
5 </ItemGroup>
然後檢視下bundleconfig.json檔案中的配置,一般預設的內容有:
1 [
2 {
3 "outputFileName": "wwwroot/css/site.min.css",
4 // An array of relative input file paths. Globbing patterns supported
5 "inputFiles": [
6 "wwwroot/css/site.css"
7 ]
8 },
9 {
10 "outputFileName": "wwwroot/js/site.min.js",
11 "inputFiles": [
12 "wwwroot/js/site.js"
13 ],
14 // Optionally specify minification options
15 "minify": {
16 "enabled": true,
17 "renameLocals": true
18 },
19 // Optionally generate .map file
20 "sourceMap": false
21 }
22 ]
我就以預設配置的js檔案和css檔案為例,執行命令: dotnet bundle 能夠看到如下效果:
此時開啟您專案的wwwroot檔案裡面的css或者js檔案,能夠看到壓縮成一行的程式碼:
賬戶設定 - 修改頭像
對於幾乎每個系統來說,賬戶設定普遍包括有修改個人資訊,頭像,密碼這3部分的操作,本篇的主要分享內容也是圍繞這3部分來講解和分享程式碼;首先來看看愛留圖開原始碼的修改頭像模組吧,對於修改頭像功能往往都是單獨的,所以我們可以通過如下介面跳轉到僅僅只有上傳頭像的介面:
修改頭像主要功能是上傳頭像,如果上傳的圖片過大就限制上傳或者系統生成一個小頭像的圖片,這樣避免使用者檢視頭像時候由於圖片過大,載入速度變慢了;來看看主要處理上傳的Action方法吧:
1 [HttpPost] 2 public async Task<IActionResult> UpHeadPhoto([Bind("Id")]MoUserInfo moUserInfo) 3 { 4 5 var file = Request.Form.Files.Where(b => 6 b.Name == "myHeadPhoto" && 7 b.ContentType.Contains("image")). 8 SingleOrDefault(); 9 if (file == null) { this.MsgBox("請選擇上傳的頭像圖片!"); return View(_MyUserInfo); } 10 11 var maxSize = 1024 * 1024 * 4; 12 if (file.Length > maxSize) 13 { 14 this.MsgBox("頭像圖片不能大於4M!"); return View(_MyUserInfo); 15 } 16 17 var fileExtend = file.FileName.Substring(file.FileName.LastIndexOf('.')); 18 var fileNewName = $"{DateTime.Now.ToString("yyyyMMddHHmmssfff")}{fileExtend}"; 19 var path = Path.Combine(_selfSetting.UpHeadPhotoPath, fileNewName); 20 using (var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite)) 21 { 22 await file.CopyToAsync(stream); 23 } 24 25 //更新資料 26 var viewPath = $"{_selfSetting.ViewHeadPhotoPath}/{fileNewName}"; 27 28 var user = _db.ToUserInfo.Where(b => b.Id == _MyUserInfo.Id).SingleOrDefault(); 29 if (user == null) { this.MsgBox("上傳失敗,請稍後重試!"); return View(_MyUserInfo); } 30 user.HeadPhoto = viewPath; 31 user.LevelNum += (int)EmLevelNum.修改頭像; 32 var result = await _db.SaveChangesAsync(); 33 if (result > 0) 34 { 35 _MyUserInfo.HeadPhoto = viewPath; 36 _MyUserInfo.LevelNum = user.LevelNum; 37 HttpContext.Session.Set<MoUserInfo>(HttpContext.Session.SessionKey(), _MyUserInfo); 38 this.MsgBox("上傳成功!"); 39 40 _db.ToUserLog.Add(new ToUserLog 41 { 42 CodeId = (int)EmLogCode.積分, 43 CreateTime = DateTime.Now, 44 Des = $"【修改頭像】 +{(int)EmLevelNum.修改頭像}", 45 UserId = _MyUserInfo.Id 46 }); 47 await _db.SaveChangesAsync(); 48 49 } 50 else { this.MsgBox("上傳失敗,請稍後重試!"); } 51 return View(_MyUserInfo); 52 }
在寫博文的時候才發現,這程式碼原來有部分多餘的寫法,仔細的朋友應該看出來了 [Bind("Id")]MoUserInfo moUserInfo 我在action中根本沒有用到呢,不知道當初寫的時候是怎麼想的哈哈,因為這裡我直接通過 Request.Form.Files 來獲取上傳的頭像圖片檔案資訊,注意了由於Files是獲取多個檔案資訊,但是我們上傳頭像的時候只會有一張圖片存在才是合理的,所以我通過上傳的元素file對應的name='myHeadPhoto'來讓files匹配出對應的檔案資訊,所以有了這樣的篩選操作:
1 Request.Form.Files.Where(b =>b.Name == "myHeadPhoto" && b.ContentType.Contains("image")).SingleOrDefault()
對於存放圖片檔案的路徑我是通過讀取配置在appsettings.json檔案中的節點配置的,正如我AspNetCore - MVC實戰系列(一)之Sqlserver表對映實體模型寫到的怎麼通過Options獲取appsettings.json檔案配置資訊是一樣的操作,如果你可以直接取那裡看吧;然後通過 await file.CopyToAsync(stream); 來拷貝複製檔案流到生成的圖片檔案裡面,以此完成上傳功能;至於其他的新增積分,上傳記錄日誌等這些都是業務需要的操作,這裡不在詳解;
賬戶設定 - 修改基本資訊
基本資訊的修改沒有什麼特別的地方,提一下注意點對於一個登陸使用者來說,修改了基本資訊,如果你session儲存有這些資訊也同樣在更新資料表資料的時候也需要更新session儲存的資訊,這樣才能保證修改後,使用者看到的是修改的內容;
1 [HttpPost] 2 public async Task<IActionResult> ModifyUser(MoUserInfo moUserInfo) 3 { 4 if (moUserInfo.Id <= 0) 5 { 6 this.MsgBox("修改失敗,請稍後重試。"); 7 return View(_MyUserInfo); 8 } 9 else if (string.IsNullOrWhiteSpace(moUserInfo.NickName)) 10 { 11 this.MsgBox("暱稱不能為空!"); 12 return View(_MyUserInfo); 13 } 14 15 _MyUserInfo.NickName = moUserInfo.NickName; 16 _MyUserInfo.Tel = moUserInfo.Tel; 17 _MyUserInfo.Sex = moUserInfo.Sex; 18 _MyUserInfo.Birthday = moUserInfo.Birthday; 19 20 _MyUserInfo.Blog = moUserInfo.Blog; 21 _MyUserInfo.Introduce = moUserInfo.Introduce; 22 23 var user = _db.ToUserInfo.Where(b => b.Id == _MyUserInfo.Id).SingleOrDefault(); 24 if (user == null) { this.MsgBox("修改失敗,請稍後重試"); return View(_MyUserInfo); } 25 26 user.NickName = _MyUserInfo.NickName; 27 user.Tel = _MyUserInfo.Tel; 28 user.Sex = _MyUserInfo.Sex; 29 user.Birthday = _MyUserInfo.Birthday; 30 31 user.Blog = _MyUserInfo.Blog; 32 user.Introduce = _MyUserInfo.Introduce; 33 34 var result = await _db.SaveChangesAsync(); 35 if (result > 0) 36 { 37 HttpContext.Session.Set<MoUserInfo>(HttpContext.Session.SessionKey(), _MyUserInfo); 38 this.MsgBox("修改成功!"); 39 } 40 else { this.MsgBox("修改失敗,請稍後重試!"); } 41 42 return View(_MyUserInfo); 43 }
為了避免分享的內容枯燥性,這裡分享一些通用方法,如使用者繫結了手機號或郵箱,處於安全考慮這些是不能直接在web網頁展示出來的需要類似於:8312***333.com的*號來遮蔽,這裡提供個擴充套件方法:
1 /// <summary> 2 /// 格式化安全資訊 3 /// </summary> 4 /// <param name="val"></param> 5 /// <param name="startLen"></param> 6 /// <param name="endLen"></param> 7 /// <returns></returns> 8 public static string FomartPhone(this string val, int startLen = 3, int endLen = 3) 9 { 10 if (string.IsNullOrWhiteSpace(val)) { return ""; } 11 12 var len = val.Trim().Length; 13 var start = string.Empty; 14 var end = string.Empty; 15 if (len > startLen) { start = val.Substring(0, startLen); } else { start = val; } 16 if (len - endLen > startLen) { end = val.Substring(len - endLen, endLen); } 17 return string.Format("{0}***{1}", start, end); 18 }
很簡單的吧,不過這種也是很常用並且是需要的一個方法,用起來僅僅只需要這樣: Model.Email.FomartPhone(startLen:4,endLen:4) ;再來個計算註冊時間距離現在多少天多少月多少年的方法:
1 /// <summary> 2 /// 獲取據當前時間的時間間隔:如1年1月1日 3 /// </summary> 4 /// <param name="date"></param> 5 /// <param name="yearNum"></param> 6 /// <param name="monthNum"></param> 7 /// <returns></returns> 8 public static string FormatDateToNow(this DateTime date, int yearNum = 365, int monthNum = 31) 9 { 10 var subTime = DateTime.Now.Subtract(date); 11 12 var dayNum = subTime.Days; 13 14 var year = dayNum / yearNum; 15 var month = dayNum % yearNum / monthNum; 16 var day = dayNum % yearNum % monthNum; 17 18 var str = year > 0 ? $"{year}年" : ""; 19 str += month > 0 ? $"{month}月" : ""; 20 str += day > 0 ? $"{day}天" : "1天"; 21 22 return str; 23 }
由於也是擴充套件的DateTime的方法,所以可以直接這樣用 @Model.CreateTime.FormatDateToNow() ,然後看起來的效果是這樣:
賬戶設定 - 修改密碼
修改密碼這東西往往需要很多驗證,主要為了防盜;應對這些防盜的方法有繫結郵箱,繫結手機號碼,在AspNetCore-MVC實戰系列(二)之通過繫結郵箱找回密碼已經講解了如果通過繫結郵箱找回密碼的流程,有需要的朋友可以參考下,主要通過傳送重置密碼連結,修改密碼;由於偷懶賬戶設定的修改密碼,我就沒有做這麼多的流程驗證了,僅僅只需要填寫密碼和重複密碼即可:
1 public IActionResult ModifyPwd() 2 { 3 return View(new MoRegisterUser { UserName = _MyUserInfo.UserName }); 4 } 5 6 [HttpPost] 7 public async Task<IActionResult> ModifyPwd([Bind("UserName,UserPwd,ComfirmPwd")]MoRegisterUser moRegisterUser) 8 { 9 if (ModelState.IsValid) 10 { 11 var user = _db.ToUserInfo.Where(b => b.Id == _MyUserInfo.Id).SingleOrDefault(); 12 if (user == null) { this.MsgBox("修改失敗,請稍後重試"); return View(moRegisterUser); } 13 user.UserPwd = PublicClass._Md5(moRegisterUser.UserPwd.Trim()); 14 var result = await _db.SaveChangesAsync(); 15 if (result > 0) 16 {18 this.MsgBox("修改成功!"); 19 } 20 else { this.MsgBox("修改失敗,請稍後重試!"); } 21 } 22 return View(moRegisterUser); 23 }
結尾告白
到這裡AspNetCore-MVC實戰系列基本就講解的差不多了,內容主要以業務場景居多,基本都是很常見的功能,程式碼也已經開源分享了,剛接觸netcore並且有興趣的朋友可以參考;老實說對於這種感覺沒有什麼特別之處的功能講解很費勁的,不過在本次開發過程中遇到的一些問題還是值得了解下的,這些都分享在每張講解的內容裡面了,需要注意看下才能發現總結的經驗;最近在做公司系統,該系統會大量的傳送郵件,因此簡單構思了個郵件系統,如果可以將再下一篇和大家分享;謝謝大家的支援。