日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例)

發(fā)布時(shí)間:2023/12/13 c/c++ 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

  在上一篇0_MVC+EF+Autofac(dbfirst)輕型項(xiàng)目框架_基本框架中,我已經(jīng)介紹了這個(gè)輕型框架的層次結(jié)構(gòu),在下面的這篇文章中,我將以教師登陸功能為例,具體來(lái)擴(kuò)充下我的core層的代碼。

  在這之前,我想先補(bǔ)充討論下是否有必要添加server層,因?yàn)榭催^(guò)不少別人的框架都有這一層。首先,server層在不同地方有著不同的解釋。有個(gè)常聽(tīng)的詞叫MVSC,這里所指的S雖然也是server的意思,但實(shí)現(xiàn)的功能更有點(diǎn)類似于我框架中的core,主要存放也是業(yè)務(wù)邏輯。但我看了別人框架上的server層,有些甚至已經(jīng)直接繼承自Controller類,一開(kāi)始很不解,這樣做讓web層中的Controller顏面何存。但在深入了解了mvc的一些機(jī)制后覺(jué)得這樣做也有道理(mvc在注冊(cè)控制器時(shí)是遍歷文件夾中的dll來(lái)的),把視圖和控制器存放在了不同的程序集里,便于團(tuán)隊(duì)開(kāi)發(fā)。但有些server層的作用更像是單純?yōu)榱私oweb(view)和core解耦或者說(shuō)是改變依賴關(guān)系。具體我還真的沒(méi)能力來(lái)討論這么做有沒(méi)有必要,別人這么做必然有別人的出發(fā)點(diǎn)和目的,但在我的輕量架構(gòu)中還是沒(méi)有引入server這個(gè)層,因?yàn)樵谝欢ǔ潭壬纤粫?huì)增加框架整體的復(fù)雜性,“輕”還是主基調(diào)。

  同樣,文中有問(wèn)題的地方歡迎批評(píng)指正!謝謝!

創(chuàng)建過(guò)程

  1.首先數(shù)據(jù)表結(jié)構(gòu)如下圖

  

  表中ID是教師的GUID,TID才是用來(lái)登陸的唯一標(biāo)示,PID是權(quán)限的標(biāo)示,接下去講權(quán)限判斷時(shí)將會(huì)提到它。

  2.根據(jù)數(shù)據(jù)庫(kù)生成edmx在Model層的Entity中

  3.在ICore中創(chuàng)建教師類接口,在Core中創(chuàng)建教師類

  接口中很簡(jiǎn)單,就一句話,定義了教師類的接口。

public partial interface ITeacher{}

  在Core中創(chuàng)建一個(gè)類用來(lái)實(shí)現(xiàn)ITeacher接口

public partial class Teacher : BaseCore<Entity.Teacher>, ICore.ITeacher{public Teacher(DbContext dbContext){db = dbContext;}}

  BaseCore是什么?不要驚慌。在上一篇中,我談到了我將不引入DAL層來(lái)再次封裝EF,但在EF中,有些操作比較復(fù)雜,例如修改刪除等。如果每次使用時(shí)都要先查找再修改,要寫很多重復(fù)代碼,我的BaseCore是對(duì)這些方法的一些封裝,雖然會(huì)造成一些代碼的污染,但著實(shí)可以少寫不少重復(fù)代碼。也許會(huì)有人提出異議,這樣的行為是否可以理解成是對(duì)EF的封裝?我也不能完全否認(rèn),但我更愿意把它理解成業(yè)務(wù)層對(duì)于操作EF的幫助類:

    第一,相對(duì)于單獨(dú)做一層來(lái)看,這樣更“輕”

    第二,這樣做放在業(yè)務(wù)上也更加合適,例如不需要去考慮“分頁(yè)該不該放在DAL?”這類永遠(yuǎn)討論不出正確答案的問(wèn)題

    第三,維護(hù)更簡(jiǎn)單

    第四,既然是幫助類,那就提供了不用它的可能,覺(jué)得不爽不用它就是

  以下是BaseCore的代碼,有點(diǎn)長(zhǎng)。幫助類中借鑒了部分他人分享的代碼,實(shí)在找不到出處了,這里表示感謝!

1 using System; 2 using System.Collections.Generic; 3 using System.Data.Entity; 4 using System.Data.Entity.Infrastructure; 5 using System.Linq; 6 using System.Linq.Expressions; 7 using System.Reflection; 8 using System.Text; 9 10 namespace EDUA_Core 11 { 12 /// <summary> 13 /// 業(yè)務(wù)幫助父類 14 /// </summary> 15 /// <typeparam name="T">之類類型</typeparam> 16 public class BaseCore<T> where T : class,new() 17 { 18 /// <summary> 19 /// EF上下文對(duì)象 20 /// </summary> 21 protected DbContext db { get; set; } 22 23 #region 1.0新增實(shí)體 + void Add(T model) 24 /// <summary> 25 /// 新增實(shí)體 26 /// </summary> 27 /// <param name="model">新增的實(shí)體</param> 28 protected void Add(T model) 29 { 30 db.Set<T>().Add(model); 31 } 32 #endregion 33 34 #region 1.0.1新增實(shí)體并保存 + int AddAndSave(T model) 35 /// <summary> 36 /// 新增實(shí)體并保存 37 /// </summary> 38 /// <param name="model">新增的實(shí)體</param> 39 /// <returns>受影響的行數(shù)</returns> 40 protected int AddAndSave(T model) 41 { 42 Add(model); 43 return db.SaveChanges(); 44 } 45 #endregion 46 47 #region 2.0刪除實(shí)體 + void Del(T model) 48 /// <summary> 49 /// 刪除實(shí)體 50 /// </summary> 51 /// <param name="model">刪除的實(shí)體</param> 52 protected void Del(T model) 53 { 54 db.Set<T>().Attach(model); 55 db.Set<T>().Remove(model); 56 } 57 #endregion 58 59 #region 2.0.1刪除實(shí)體并保存 + int DelAndSave(T model) 60 /// <summary> 61 /// 刪除實(shí)體并保存 62 /// </summary> 63 /// <param name="model">刪除的實(shí)體</param> 64 /// <returns>受影響的行數(shù)</returns> 65 protected int DelAndSave(T model) 66 { 67 Del(model); 68 return db.SaveChanges(); 69 } 70 #endregion 71 72 #region 2.1根據(jù)條件刪除 + void DelBy(Expression<Func<T, bool>> delWhere) 73 /// <summary> 74 /// 根據(jù)條件刪除 75 /// </summary> 76 /// <param name="delWhere">條件</param> 77 protected void DelBy(Expression<Func<T, bool>> delWhere) 78 { 79 //3.1查詢要?jiǎng)h除的數(shù)據(jù) 80 List<T> listDeleting = db.Set<T>().Where(delWhere).ToList(); 81 //3.2將要?jiǎng)h除的數(shù)據(jù) 用刪除方法添加到 EF 容器中 82 listDeleting.ForEach(u => 83 { 84 db.Set<T>().Attach(u);//先附加到 EF容器 85 db.Set<T>().Remove(u);//標(biāo)識(shí)為 刪除 狀態(tài) 86 }); 87 } 88 #endregion 89 90 #region 2.1.1根據(jù)條件刪除并保存 + int DelByAndSave(Expression<Func<T, bool>> delWhere) 91 /// <summary> 92 /// 根據(jù)條件刪除并保存 93 /// </summary> 94 /// <param name="delWhere">條件</param> 95 /// <returns>受影響的行數(shù)</returns> 96 protected int DelByAndSave(Expression<Func<T, bool>> delWhere) 97 { 98 DelBy(delWhere); 99 return db.SaveChanges(); 100 } 101 #endregion 102 103 #region 3.0修改實(shí)體 + void Modify(T model, params string[] proNames) 104 /// <summary> 105 /// 修改,如: 106 /// T u = new T() { uId = 1, uLoginName = "asdfasdf" }; 107 /// this.Modify(u, "uLoginName"); 108 /// </summary> 109 /// <param name="model">要修改的實(shí)體對(duì)象</param> 110 /// <param name="proNames">要修改的 屬性 名稱</param> 111 protected void Modify(T model, params string[] proNames) 112 { 113 //4.1將 對(duì)象 添加到 EF中 114 DbEntityEntry entry = db.Entry<T>(model); 115 //4.2先設(shè)置 對(duì)象的包裝 狀態(tài)為 Unchanged 116 entry.State = (System.Data.Entity.EntityState)System.Data.EntityState.Unchanged; 117 //4.3循環(huán) 被修改的屬性名 數(shù)組 118 foreach (string proName in proNames) 119 { 120 //4.4將每個(gè) 被修改的屬性的狀態(tài) 設(shè)置為已修改狀態(tài);后面生成update語(yǔ)句時(shí),就只為已修改的屬性 更新 121 entry.Property(proName).IsModified = true; 122 } 123 } 124 #endregion 125 126 #region 3.0.1修改和保存 + int ModifyAndSave(T model, params string[] proNames) 127 /// <summary> 128 /// 修改和保存,如: 129 /// T u = new T() { uId = 1, uLoginName = "asdfasdf" }; 130 /// this.Modify(u, "uLoginName"); 131 /// </summary> 132 /// <param name="model">要修改的實(shí)體對(duì)象</param> 133 /// <param name="proNames">要修改的 屬性 名稱</param> 134 /// <returns>受影響的行數(shù)</returns> 135 protected int ModifyAndSave(T model, params string[] proNames) 136 { 137 Modify(model, proNames); 138 return db.SaveChanges(); 139 } 140 #endregion 141 142 #region 3.1批量修改 + void ModifyBy(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames) 143 /// <summary> 144 /// 批量修改 145 /// </summary> 146 /// <param name="model">要修改的實(shí)體對(duì)象</param> 147 /// <param name="whereLambda">查詢條件</param> 148 /// <param name="proNames">要修改的 屬性 名稱</param> 149 protected void ModifyBy(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames) 150 { 151 //4.1查詢要修改的數(shù)據(jù) 152 List<T> listModifing = db.Set<T>().Where(whereLambda).ToList(); 153 154 //獲取 實(shí)體類 類型對(duì)象 155 Type t = typeof(T); // model.GetType(); 156 //獲取 實(shí)體類 所有的 公有屬性 157 List<PropertyInfo> proInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList(); 158 //創(chuàng)建 實(shí)體屬性 字典集合 159 Dictionary<string, PropertyInfo> dictPros = new Dictionary<string, PropertyInfo>(); 160 //將 實(shí)體屬性 中要修改的屬性名 添加到 字典集合中 鍵:屬性名 值:屬性對(duì)象 161 proInfos.ForEach(p => 162 { 163 if (modifiedProNames.Contains(p.Name)) 164 { 165 dictPros.Add(p.Name, p); 166 } 167 }); 168 169 //4.3循環(huán) 要修改的屬性名 170 foreach (string proName in modifiedProNames) 171 { 172 //判斷 要修改的屬性名是否在 實(shí)體類的屬性集合中存在 173 if (dictPros.ContainsKey(proName)) 174 { 175 //如果存在,則取出要修改的 屬性對(duì)象 176 PropertyInfo proInfo = dictPros[proName]; 177 //取出 要修改的值 178 object newValue = proInfo.GetValue(model, null); //object newValue = model.uName; 179 180 //4.4批量設(shè)置 要修改 對(duì)象的 屬性 181 foreach (T usrO in listModifing) 182 { 183 //為 要修改的對(duì)象 的 要修改的屬性 設(shè)置新的值 184 proInfo.SetValue(usrO, newValue, null); //usrO.uName = newValue; 185 } 186 } 187 } 188 } 189 #endregion 190 191 #region 3.1.1批量修改并保存 + int ModifyByAndSave(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames) 192 /// <summary> 193 /// 批量修改并保存 194 /// </summary> 195 /// <param name="model">要修改的實(shí)體對(duì)象</param> 196 /// <param name="whereLambda">查詢條件</param> 197 /// <param name="proNames">要修改的 屬性 名稱</param> 198 /// <returns>受影響的行數(shù)</returns> 199 protected int ModifyByAndSave(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedProNames) 200 { 201 ModifyBy(model, whereLambda, modifiedProNames); 202 return db.SaveChanges(); 203 } 204 #endregion 205 206 #region 4.0根據(jù)條件獲取記錄條數(shù) + int GetCountBy(Expression<Func<T, bool>> whereLambda) 207 /// <summary> 208 /// 根據(jù)條件獲取記錄條數(shù) 209 /// </summary> 210 /// <returns>總記錄條數(shù)</returns> 211 protected int GetCountBy(Expression<Func<T, bool>> whereLambda) 212 { 213 return db.Set<T>().Where(whereLambda).Count(); 214 } 215 #endregion 216 217 #region 5.0獲取所有記錄 + List<T> GetAllList() 218 /// <summary> 219 /// 獲取所有記錄 220 /// </summary> 221 /// <returns>返回的集合</returns> 222 protected List<T> GetAllList() 223 { 224 return db.Set<T>().ToList(); 225 } 226 #endregion 227 228 #region 5.1根據(jù)條件查詢 + List<T> GetListBy(Expression<Func<T, bool>> whereLambda) 229 /// <summary> 230 /// 根據(jù)條件查詢 231 /// </summary> 232 /// <param name="whereLambda">條件Lambda表達(dá)式</param> 233 /// <returns>返回的集合</returns> 234 protected List<T> GetListBy(Expression<Func<T, bool>> whereLambda) 235 { 236 return db.Set<T>().Where(whereLambda).ToList(); 237 } 238 #endregion 239 240 #region 5.2根據(jù)條件 排序 和查詢 + List<T> GetListBy<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderLambda, bool IsDes = false) 241 /// <summary> 242 /// 根據(jù)條件 排序 和查詢 243 /// </summary> 244 /// <typeparam name="TKey">排序字段類型</typeparam> 245 /// <param name="whereLambda">查詢條件 lambda表達(dá)式</param> 246 /// <param name="orderLambda">排序條件 lambda表達(dá)式</param> 247 /// // <param name="IsDes">是否逆序</param> 248 /// <returns>返回的集合</returns> 249 protected List<T> GetListBy<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderLambda, bool IsDes = false) 250 { 251 if(IsDes) 252 return db.Set<T>().Where(whereLambda).OrderByDescending(orderLambda).ToList(); 253 return db.Set<T>().Where(whereLambda).OrderBy(orderLambda).ToList(); 254 } 255 #endregion 256 257 #region 5.3分頁(yè)查詢 + List<T> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderBy, bool IsDes = false) 258 /// <summary> 259 /// 分頁(yè)查詢 260 /// </summary> 261 /// <param name="pageIndex">頁(yè)碼</param> 262 /// <param name="pageSize">頁(yè)容量</param> 263 /// <param name="whereLambda">條件 lambda表達(dá)式</param> 264 /// <param name="orderBy">排序 lambda表達(dá)式</param> 265 /// <param name="IsDes">是否逆序</param> 266 /// <returns>返回的集合</returns> 267 protected List<T> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderBy, bool IsDes = false) 268 { 269 if (IsDes) 270 return db.Set<T>().Where(whereLambda).OrderByDescending(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); 271 return db.Set<T>().Where(whereLambda).OrderBy(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); 272 } 273 #endregion 274 275 } 276 } View Code

?  可以看出,在上面的代碼中,我提供了增刪改查的大部分方法,對(duì)于寫入性的操作,我提供了是否立刻SaveChange的選擇,如果立刻save,可以調(diào)用類似于AddAndSave()這樣的方法,如果想多次調(diào)用后統(tǒng)一保存以提高性能,可以調(diào)用Add()這類方法,在所有操作結(jié)束后,再調(diào)用saveChange的方法。這個(gè)幫助類中存在一個(gè)DbContext類型的屬性,它用來(lái)存放ef上下文,在teacher的實(shí)現(xiàn)類中,提供了它的構(gòu)造方法,將dbcontext傳入。幫助類中幾乎所有的操作都依賴于這個(gè)DbContext。

  上面teacher的接口和實(shí)現(xiàn)都是有partial修飾,是一個(gè)部分類(接口),這樣做的目的是為了便于管理,例如日后需要添加一個(gè)學(xué)生類時(shí)可以這樣

1 public partial class Student : BaseCore<Entity.Student>, ICore.IStudent 2 { 3 public Student(DbContext dbContext) 4 { 5 db = dbContext; 6 } 7 } 8 9 public partial class Teacher : BaseCore<Entity.Teacher>, ICore.ITeacher 10 { 11 public Teacher(DbContext dbContext) 12 { 13 db = dbContext; 14 } 15 }

  這些代碼是重復(fù)的,可將它們寫在同一個(gè)cs中,如果有需要可以用T4模板自動(dòng)生成,但事實(shí)上并不是每張表都需要生成對(duì)應(yīng)的實(shí)體,所以我選擇手動(dòng)來(lái)添加它們。教師和學(xué)生具體的登陸的邏輯可能不同,將它們放在另一個(gè)partial類中會(huì)更加合理。

  4.創(chuàng)建教師的部分接口和部分類

  接口如下 

1 public partial interface ITeacher 2 { 3 #region 教師登錄 + ReturnVal Login(string tid, string pwd); 4 /// <summary> 5 /// 教師登錄 6 /// </summary> 7 /// <param name="tid">教師id</param> 8 /// <param name="pwd">密碼</param> 9 /// <returns>約定返回類型</returns> 10 ReturnVal Login(string tid, string pwd); 11 #endregion 12 }

  實(shí)現(xiàn)如下

1 public partial class Teacher 2 { 3 4 #region 教師登錄操作 + WebModel.ReturnVal Login(string tid, string pwd) 5 /// <summary> 6 /// 教師登錄操作 7 /// </summary> 8 /// <param name="tid">教師登錄名</param> 9 /// <param name="pwd">密碼</param> 10 /// <returns>約定返回類</returns> 11 public WebModel.ReturnVal Login(string tid, string pwd) 12 { 13 int iTID = Convert.ToInt32(tid); 14 Entity.Teacher teacher = this.GetListBy(t => (t.TID == iTID) && (t.IsDel == false)).ToList().FirstOrDefault(); 15 if (teacher == null) 16 { 17 return new ReturnVal(ReturnStatu.Failure, "用戶不存在"); 18 } 19 else 20 { 21 if (EDUA_Util.EncrypHelper.MD5(pwd) == teacher.Password) 22 { 23 return new ReturnVal(ReturnStatu.Success, "登陸成功", WebModel.Teacher.ToWebModel(teacher)); 24 } 25 else 26 { 27 return new ReturnVal(ReturnStatu.Failure, "密碼錯(cuò)誤"); 28 } 29 } 30 } 31 #endregion 32 }

  很簡(jiǎn)單,首先判斷用戶是否存在,接下去判斷密碼是否正確。

  第13行,這里我使用了我的basecore里的方法,如果不想用也很簡(jiǎn)單。

  返回值類型為ReturnVal,這是我自己的類,原因是不能簡(jiǎn)單地用一個(gè)bool值來(lái)傳遞登陸成功與否,如果登陸成功了需要將對(duì)象返回保存在cookie,session中,以保證狀態(tài)的維持。ReturnVal也會(huì)被用在其他core與web傳遞數(shù)據(jù)的過(guò)程中。ReturnVal類如下

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace WebModel 8 { 9 /// <summary> 10 /// 返回值約定 11 /// 從core 到 web 返回內(nèi)容的封裝 12 /// </summary> 13 public class ReturnVal 14 { 15 #region 屬性 16 /// <summary> 17 /// 返回的狀態(tài) 18 /// </summary> 19 public ReturnStatu Statu { get; set; } 20 /// <summary> 21 /// 返回的消息 22 /// </summary> 23 public string Message { get; set; } 24 /// <summary> 25 /// 返回的數(shù)據(jù) 26 /// </summary> 27 public object Data { get; set; } 28 #endregion 29 30 #region 構(gòu)造方法 31 /// <summary> 32 /// 構(gòu)造方法 33 /// </summary> 34 /// <param name="statu">狀態(tài)</param> 35 public ReturnVal(ReturnStatu statu) 36 { 37 this.Statu = statu; 38 } 39 /// <summary> 40 /// 構(gòu)造方法 41 /// </summary> 42 /// <param name="statu">狀態(tài)</param> 43 /// <param name="message">消息</param> 44 public ReturnVal(ReturnStatu statu, string message) 45 : this(statu) 46 { 47 this.Message = message; 48 } 49 /// <summary> 50 /// 構(gòu)造方法 51 /// </summary> 52 /// <param name="statu">狀態(tài)</param> 53 /// <param name="message">消息</param> 54 /// <param name="data">數(shù)據(jù)</param> 55 public ReturnVal(ReturnStatu statu, string message, object data) 56 : this(statu, message) 57 { 58 this.Data = data; 59 } 60 #endregion 61 } 62 63 64 /// <summary> 65 /// 狀態(tài)枚舉 66 /// </summary> 67 public enum ReturnStatu 68 { 69 /// <summary> 70 /// 成功 71 /// </summary> 72 Success, 73 /// <summary> 74 /// 失敗 75 /// </summary> 76 Failure, 77 /// <summary> 78 /// 錯(cuò)誤 79 /// </summary> 80 Err 81 } 82 } View Code

  ReturnVal在WebModel程序集下,同樣在該程序集下的還有上面用到的WebModel.Teacher。按照常理,EF和View之間存在著Core層,故View不可直接依賴于EF,所以它們之間需要一層WebModel來(lái)傳遞。WebModel的存在類似于DTO,它可以剝離那些上層中用不到的字段,以下是我的WebModel中的Teacher類,為了方便,里面提供了將實(shí)體類轉(zhuǎn)換為WebModel類的靜態(tài)方法,也是上面所用到的。

1 namespace WebModel 2 { 3 public class Teacher 4 { 5 #region 屬性 6 /// <summary> 7 /// guid 8 /// </summary> 9 public System.Guid ID { get; set; } 10 /// <summary> 11 /// 學(xué)號(hào) 12 /// </summary> 13 public int TID { get; set; } 14 /// <summary> 15 /// 姓名 16 /// </summary> 17 public string Name { get; set; } 18 /// <summary> 19 /// 權(quán)限列表 20 /// </summary> 21 public List<Authority> AuthorityList { get; set; } 22 #endregion 23 24 #region 轉(zhuǎn)化為視圖類的teacher + static Teacher ToWebModel(Entity.Teacher et) 25 /// <summary> 26 /// 轉(zhuǎn)化為視圖類的teacher 27 /// </summary> 28 /// <param name="es">實(shí)體類</param> 29 /// <returns>視圖類</returns> 30 public static Teacher ToWebModel(Entity.Teacher et) 31 { 32 List<Entity.AuthorityToPower> Listatp = et.Power.AuthorityToPowers.ToList(); 33 List<Authority> ListAut = new List<Authority>(); 34 Listatp.ForEach(au => { 35 ListAut.Add(Authority.ToWebModel(au.Authority)); 36 }); 37 return new Teacher() 38 { 39 Name = et.Name, 40 TID = et.TID, 41 ID = et.ID, 42 AuthorityList = ListAut 43 }; 44 } 45 #endregion 46 }

?

  上面還用到了類似于EDUA_Util.EncrypHelper.MD5這類MD5加密算法,我將它們放到工具類中。它們?cè)诓煌捻?xiàng)目中可以完全復(fù)用,類似這樣的方法還有加密解密cookie,生隨機(jī)數(shù)(封裝過(guò)),生成驗(yàn)證碼,導(dǎo)入導(dǎo)出Excel等等。將它們統(tǒng)統(tǒng)放到Util中還可以將很多第三方的引用添加到這個(gè)程序集中,保證上層程序集的整潔,它們是整個(gè)項(xiàng)目的Infrastructure(基礎(chǔ)設(shè)施)。

  5.在ICoreSession,CoreSession中分別創(chuàng)建Teacher類

  上一篇中提到過(guò),在web中的控制器中可以調(diào)用到iCoreSession,所以想要在web層調(diào)用core中teacher的login方法,就需要在ICoreSession中存在teacher對(duì)象。故接口中的代碼如下

1 public interface ICoreSession 2 { 3 ITeacher ITeacher { get; } 4 }

  CoreSession中的代碼如下,這樣保證了在一次請(qǐng)求中teacher的單例,通過(guò)構(gòu)造方法將db對(duì)象傳入到teacher類中。

1 public class CoreSession:EDUA_ICore.ICoreSession 2 { 3 4 #region 屬性 5 private DbContext db { get; set; } 6 #endregion 7 8 #region 構(gòu)造方法 9 public CoreSession() 10 { 11 db = new Entity.EDUAEntities(); 12 } 13 #endregion 14 15 #region 保存 + int SaveChanges() 16 /// <summary> 17 /// 保存修改 18 /// </summary> 19 /// <returns>受影響的行數(shù)</returns> 20 public int SaveChanges() 21 { 22 return db.SaveChanges(); 23 } 24 #endregion 25 26 ITeacher iTeacher; 27 public ITeacher ITeacher 28 { 29 get 30 { 31 if (iTeacher == null) 32 { 33 iTeacher = new Teacher(db); 34 } 35 return iTeacher; 36 } 37 } 38 }

?  6.創(chuàng)建Login頁(yè)面

  控制器

#region 1.0 登陸界面 [HttpGet] public ActionResult Login() {return View(); } #endregion

  頁(yè)面為強(qiáng)類型頁(yè)面,使用了微軟的數(shù)據(jù)驗(yàn)證,所以需要導(dǎo)入微軟所提供的js?@Scripts.Render("~/Scripts/mvcAjax") ?使用App_Statr中的BundleConfig進(jìn)行了綁定。

  

  視圖中的類型類為WebModel.LoginUser,它同樣放在webmodel程序集下的,我單獨(dú)創(chuàng)建了ViewModel文件夾用來(lái)存放這些類,其實(shí)將它們放在web層也是合理的。對(duì)應(yīng)的代碼以及頁(yè)面如下。

1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel.DataAnnotations; 4 using System.Linq; 5 using System.Web; 6 7 namespace WebModel 8 { 9 10 /// <summary> 11 /// 登陸視圖 模型 12 /// </summary> 13 public class LoginUser 14 { 15 /// <summary> 16 /// 用戶名 17 /// </summary> 18 [Required(ErrorMessage = "用戶名不能為空")] 19 public int LoginName { get; set; } 20 /// <summary> 21 /// 密碼 22 /// </summary> 23 [Required(ErrorMessage = "密碼不能為空")] 24 public string Pwd { get; set; } 25 /// <summary> 26 /// 驗(yàn)證碼 27 /// </summary> 28 [Required(ErrorMessage = "請(qǐng)輸入驗(yàn)證碼")] 29 public string VCode { get; set; } 30 /// <summary> 31 /// 身份 1 為教師 0為學(xué)生 32 /// </summary> 33 [Required(ErrorMessage = "請(qǐng)輸選擇身份")] 34 public int Degree { get; set; } 35 /// <summary> 36 /// 是否記住 37 /// </summary> 38 public bool IsAlways { get; set; } 39 } 40 41 } @model WebModel.LoginUser @{Layout = null; } <html> <head><title>登陸</title><meta charset="utf-8" /><meta name="viewport" content="width=device-width" />@Scripts.Render("~/Scripts/mvcAjax")<style type="text/css">.p_main {margin-left: auto;margin-right: auto;width: 400px;margin-top: 45px;}.SingleLine {padding-top: 10px;}.alert {color: red;}#divMsg {display: none;}</style><script type="text/javascript">$(function () {$("#img_Vcode").click(function () {newVcode();});});//請(qǐng)求一個(gè)新的驗(yàn)證碼function newVcode() {$("#img_Vcode").attr("src", "/helper/VCode/" + Math.round(Math.random() * 100000));}function Success(jsDate) {if (jsDate.Statu == "err") {$("#td_msg").html(jsDate.Msg);newVcode();}else if (jsDate.Statu == "ok") {window.location.href = jsDate.BackUrl;}}</script> </head> <body><div class="p_main"><div class="div_main">@using (Ajax.BeginForm(new AjaxOptions(){HttpMethod = "post",OnSuccess = "Success",LoadingElementId = "divMsg"})){<div class="SingleLine"><div style="float:left;width:80px;font-size:15px">登陸身份:</div><div><input type="radio" name="Degree" id="Degree0" value="0"><label for="Degree0">學(xué)生</label><input type="radio" name="Degree" id="Degree1" value="1" checked="checked"><label for="Degree1">教師</label></div></div><div style="clear:both"></div><div class="SingleLine"><div style="float:left;width:80px;font-size:15px">用戶名:</div><div style="float:left">@Html.TextBoxFor(u => u.LoginName)</div><div style="float:left" class="alert">@Html.ValidationMessageFor(u => u.LoginName)</div></div><div style="clear:both"></div><div class="SingleLine"><div style="float:left;width:80px;font-size:15px">密碼:</div><div style="float:left">@Html.PasswordFor(u => u.Pwd)</div><div style="float:left" class="alert">@Html.ValidationMessageFor(u => u.Pwd)</div></div><div style="clear:both"></div><div class="SingleLine"><div style="float:left;width:80px;font-size:15px">驗(yàn)證碼:</div><div style="float:left">@Html.TextBoxFor(u => u.VCode)</div><div style="float:left"><img id="img_Vcode" src="/helper/VCode"></div><div style="float:left" class="alert">@Html.ValidationMessageFor(u => u.VCode)</div></div><div style="clear:both"></div><div class="SingleLine"><div style="float:left;padding-right:100px;">@Html.CheckBoxFor(u => u.IsAlways) <span>兩小時(shí)內(nèi)免登陸</span></div><div style="float:left"><input type="submit" value="登陸" /><div id="divMsg">登陸中~~~</div></div> <div id="td_msg" class="alert"></div> </div>}</div></div> </body> </html>

?

  實(shí)際的項(xiàng)目中,在登錄時(shí)選擇登陸身份,有教師或?qū)W生可選,它們公用一個(gè)登陸入口,在控制器中根據(jù)頁(yè)面?zhèn)骰貋?lái)的信息選擇調(diào)用teacher的login方法或者是student的login方法。前臺(tái)我用了EasyUI。

  7.控制器中的登陸處理

  在控制器中,通過(guò)調(diào)用ICoreSession中teacher的login方法來(lái)進(jìn)行。

    a.判斷驗(yàn)證碼是否正確,如果錯(cuò)誤直接返回驗(yàn)證碼錯(cuò)誤的json給頁(yè)面

    b.判斷用戶所選擇的登陸身份(學(xué)生的沒(méi)有寫)

    c.調(diào)用core中teacher的登陸方法,傳入用戶名和密碼

    d.根據(jù)返回的ReturnVal判斷登陸的狀態(tài),如果成功寫入Session

    e.判斷是否需要寫入cookie,如有需要,則寫入

    f.跳轉(zhuǎn)到對(duì)應(yīng)的頁(yè)面

1 #region 1.1 登錄操作 2 [HttpPost] 3 public ActionResult Login(WebModel.LoginUser userInfo) 4 { 5 //判斷驗(yàn)證碼 為方便測(cè)試用0可跳過(guò) 6 OperateHelper.BussinessHelper h = new OperateHelper.BussinessHelper(iCoreSession); 7 if (((h.Vcode).ToLower() != (userInfo.VCode).ToLower()) && (userInfo.VCode != "0")) 8 { 9 return WebModel.JsonModel.AjaxMsgModel.RedirectAjax("err", "驗(yàn)證碼錯(cuò)誤", "", ""); 10 } 11 else 12 { 13 //學(xué)生 14 if (userInfo.Degree == 0) 15 { 16 //里面是對(duì)應(yīng)學(xué)生的登陸操作 17 } 18 //教師 19 else if (userInfo.Degree == 1) 20 { 21 ReturnVal rv = iCoreSession.ITeacher.Login(userInfo.LoginName.ToString(), userInfo.Pwd); 22 if (rv.Statu == ReturnStatu.Success) 23 { 24 h.TeacherSession = rv.Data as WebModel.Teacher; 25 //保存cookie 26 if (userInfo.IsAlways) 27 { 28 h.TeacherTIDCookie = (rv.Data as WebModel.Teacher).ID.ToString(); 29 } 30 else 31 { 32 h.TeacherTIDCookie = ""; 33 } 34 return WebModel.JsonModel.AjaxMsgModel.RedirectAjax("ok", rv.Message, "", "/teacher/teacherhome/index"); 35 } 36 else 37 { 38 return WebModel.JsonModel.AjaxMsgModel.RedirectAjax("err", rv.Message, "", ""); 39 } 40 } 41 else 42 { 43 return null; 44 } 45 } 46 #endregion

寫在最后

  至此,登陸功能算是完成了,但沒(méi)有對(duì)用戶訪問(wèn)權(quán)限的過(guò)濾,登陸操作就沒(méi)有任何意義。所以在下一篇中,我將會(huì)通過(guò)AuthorizeAttribute來(lái)實(shí)現(xiàn)用戶權(quán)限的過(guò)濾。這樣,一個(gè)最基本的架構(gòu)才算形成。

?

轉(zhuǎn)載請(qǐng)注明出處 huhuhuo的博客園

地址:http://www.cnblogs.com/linhan/p/4298971.html

轉(zhuǎn)載于:https://www.cnblogs.com/linhan/p/4298971.html

總結(jié)

以上是生活随笔為你收集整理的1_MVC+EF+Autofac(dbfirst)轻型项目框架_core层(以登陆为例)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。