序
07过去也很久了,框架体系似乎也就这样了。那会儿ibatis,spring,structs,sigmagrid搞定,好像除了ibatis改了名字,前端开始html5(用控件,也关心不多,也不属于程序员详细关心),真没多少变化。那会儿的工业架构倒是目前很多大数据互联网流行的架构(这个这会儿用不上,闲扯一下)。
摆在这也就是些增删改查的东西...
定位
一个为过检的东西,原则 —— 看的过去,省(时,力);
因此尽量维持使用微软的东西,entity framework,mvc,ace不错bootstrap、jquery;找了一圈grid还是只有用jqgrid;为了继续省,还凑合顺眼,定位单个业务页面内是ajax操作,页面间就不管了,全输出。
说一下数据库哈 —— 现成的表,超级拉拉...拉到什么程度就不说了,当然也有他的历史因素。
为了继续省,登录页干脆就不做了,弄成basic登录好了;
上点产物
代码往下继续——
(登录示意图)
(编辑示意图)
(搜索示意图)
(系统状态图)
好,
go coding...ing
实现基本认证:LAuthenticateAttribute : FilterAttribute, IAuthenticationFilter,抄来基本认证代码,加上自己的登录判断,OK搞定;
写个增删该查通用Controller:
1 [LAuthenticate] 2 public abstract class EntityControllerBase<T> : Controller where T :class 3 { 4 private readonly STGps_DataEntities _db = new STGps_DataEntities(); 5 6 public STGps_DataEntities Db 7 { 8 get { return _db; } 9 } 10 11 public DbSet<T> Table 12 { 13 get { return _db.Set<T>(); } 14 } 15 16 //protected System.Data.Entity.DbSet<T> DbSet { get;private set; } 17 public string PrimaryKey { get; private set; } 18 19 protected EntityControllerBase(string primaryKey):base() 20 {PrimaryKey = primaryKey;} 21 22 // GET: Vehicle 23 public virtual ActionResult Index() 24 { 25 return View(); 26 } 27 28 // GET: Vehicle 29 public virtual ActionResult List(GridSettings grid) 30 { 31 return List<T>(grid, null); 32 } 33 34 // GET: Vehicle 35 protected ActionResult List<TFormatEntities>(GridSettings grid, Func<IQueryable<T>, IQueryable<TFormatEntities>> formatFun) where TFormatEntities : class 36 { 37 IQueryable<T> query = Table; 38 //filtring 39 if (grid.IsSearch) 40 { 41 //And 42 if (grid.Where.groupOp == "AND") 43 foreach (var rule in grid.Where.rules) 44 query = query.Where<T>(rule.field, rule.data, rule.op); 45 else 46 { 47 //Or 48 var temp = (new List<T>()).AsQueryable(); 49 foreach (var rule in grid.Where.rules) 50 { 51 var t = query.Where<T>(rule.field, rule.data, rule.op); 52 temp = temp.Concat<T>(t); 53 } 54 //remove repeating records 55 //query = temp.Distinct<T>(); 56 } 57 } 58 //sorting 59 query = query.OrderBy<T>(grid.SortColumn, grid.SortOrder); 60 //count 61 var count = query.Count(); 62 //paging 63 var data = query.Skip((grid.PageIndex - 1) * grid.PageSize).Take(grid.PageSize); 64 //converting in grid format 65 var result = new 66 { 67 total = (int)Math.Ceiling((double)count / grid.PageSize), 68 page = grid.PageIndex, 69 records = count, 70 rows = formatFun == null ? data as IQueryable : formatFun.Invoke(data), 71 }; 72 73 //convert to JSON and return to client 74 return new LJsonResult(result, JsonRequestBehavior.AllowGet); 75 } 76 77 protected virtual IQueryable<T> FormatEntities(IQueryable<T> data) 78 { 79 return data; 80 } 81 82 public ActionResult Edit(T entity, string oper, string id) 83 { 84 switch (oper) 85 { 86 case "add": 87 return Add(entity); 88 case "del": 89 return Delete(id); 90 case "edit": 91 return Modify(entity); 92 } 93 return new HttpStatusCodeResult(HttpStatusCode.NotFound); 94 } 95 96 protected virtual HttpStatusCodeResult Add(T entity) 97 { 98 try 99 { 100 Table.Add(entity); 101 _db.Entry<T>(entity).State = EntityState.Added; 102 _db.SaveChanges(); 103 } 104 catch (Exception ex) 105 { 106 return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); 107 } 108 return new HttpStatusCodeResult(HttpStatusCode.Created); 109 } 110 111 protected virtual HttpStatusCodeResult Modify(T entity) 112 { 113 try 114 { 115 //var id0 = entity.GetType().GetProperty(PrimaryKey).GetValue(entity); 116 //_db.Set<T>().Attach(entity); 117 _db.Entry(entity).State = EntityState.Modified; 118 _db.SaveChanges(); 119 } 120 catch (Exception ex) 121 { 122 return new HttpStatusCodeResult(HttpStatusCode.InternalServerError,ex.Message); 123 } 124 return new HttpStatusCodeResult(HttpStatusCode.OK); 125 } 126 127 protected virtual HttpStatusCodeResult Delete(string id) 128 { 129 try 130 { 131 var ids = id.Split(','); 132 ids.ForEach(t => _db.Database.ExecuteSqlCommand(string.Format("Delete {0} where {1}=@id", typeof(T).Name, PrimaryKey), new SqlParameter("@id", t))); 133 } 134 catch (Exception ex) 135 { 136 return new HttpStatusCodeResult(HttpStatusCode.InternalServerError,ex.Message); 137 } 138 return new HttpStatusCodeResult(HttpStatusCode.OK); 139 } 140 141 }
这里PrimaryKey是不得不专门为这破旧的数据表留一腿;
List()是标准Entity输出,那复合怎么搞定?
—— List<TFormatEntities>这个函数正是专门为处理这个问题留出来的;
比如下面情况——
1 public virtual ActionResult ListExtDevice(GridSettings grid) 2 { 3 return List(grid, sims => sims.Select(t => new SIMExtDevice 4 { 5 Area = t.Area, 6 SIM1 = t.SIM1, 7 SIMID = t.SIMID, 8 OpenDate = t.OpenDate, 9 Status = t.Status, 10 Type = t.Type, 11 DeviceId = Db.tblTerminalManage.FirstOrDefault(f => f.TerminalTel == t.SIM1).ID, 12 })); 13 }
还是挺方便快捷的,SIMExtDevice这个也用不了什么代码 —— SIMExtDevice:SIM,然后加上复合字段Property即可;
增删该查就搞毕(不是毕姥爷)!
好像差不多了,View套上ACE,JQGrid(留个备注http://www.trirand.com/jqgridwiki/doku.php?id=wiki:jqgriddocs,说实话这比起Sigmagrid还是后起之物,真心没Sigmagrid好)...
其余的等等什么什么Controller、View都是细致的体力活,同志们加油吧~~
后
如果非要处理注销的话,basic好像没什么好办法;
chrome经过服务端定向登录错误是可以的,ie就不行了,不过还好ie有他的特殊接口。
这事反正有点扯淡,我为过检,所以省了关闭浏览器KO。
https://docs.microsoft.com/en-us/aspnet/signalr/overview/security/hub-authorization