MVC框架json數據展現程序(初版)

模型原型:服務器的配置和運行狀態信息。css

設計要求:Json格式數據解析後,判斷配置信息是不是新數據或者是否更新。如是新數據,則直接添加到數據庫;如果數據更新,則更新數據庫配置信息並更新運行狀態信息;都不是則僅將運行狀態添加到數據庫。最後從數據庫取數據並展現。html

模型難點:每一個服務器會搭載多個網卡和最多44個硬盤。jquery

(1)View層如何同時展現全部硬盤和其餘設備屬性的信息。數據庫

(2)單服務器配多網卡多硬盤一定會設計多個表(即服務器配置表、運行狀態表、網卡配置表、硬盤配置表),MVC框架下如何同時將其Model傳到View層。json

(3)本文程序使用PageList進行分頁,一般爲了程序運行速度,會在查詢時進行分頁,及var servers = db.Servers.OrderByDescending(e => e.ID).ToPagedList(pageNumber, 7),但本設計考慮到多Model傳到View層,此方法不適用。如何使程序適應上萬條數據的數據庫。bootstrap

 

Model層:服務器

 1 using System;  2 using System.Collections.Generic;  3 using System.ComponentModel;  4 using System.ComponentModel.DataAnnotations;  5 using System.Linq;  6 using System.Web;  7 
 8 namespace monitoring.Models  9 { 10     public class Servers 11  { 12         public int ID { get; set; } 13  [Required] 14         [DisplayName("主板序列號")] 15         public string AMDCDkey { get; set; } 16  [Required] 17         [DisplayName("服務器名")] 18         public string HostName { get; set; } 19  [Required] 20         [DisplayName("CPU型號")] 21         public string CPUType { get; set; } 22  [Required] 23         [DisplayName("CPU數量")] 24         public int CPUNum { get; set; } 25  [Required] 26         [DisplayName("內存大小")] 27         public string RAMSize { get; set; } 28         [DisplayName("Raid卡型號")] 29         public string RaidType { get; set; } 30  [Required] 31         [DisplayName("硬盤個數")] 32         public int HDDNum { get; set; } 33  [Required] 34         [DisplayName("機箱型號")] 35         public string CaseType { get; set; } 36  } 37 }
Servers
 1 using System;  2 using System.Collections.Generic;  3 using System.ComponentModel;  4 using System.ComponentModel.DataAnnotations;  5 using System.Linq;  6 using System.Web;  7 
 8 namespace monitoring.Models  9 { 10     public class Servers 11  { 12         public int ID { get; set; } 13  [Required] 14         [DisplayName("主板序列號")] 15         public string AMDCDkey { get; set; } 16  [Required] 17         [DisplayName("服務器名")] 18         public string HostName { get; set; } 19  [Required] 20         [DisplayName("CPU型號")] 21         public string CPUType { get; set; } 22  [Required] 23         [DisplayName("CPU數量")] 24         public int CPUNum { get; set; } 25  [Required] 26         [DisplayName("內存大小")] 27         public string RAMSize { get; set; } 28         [DisplayName("Raid卡型號")] 29         public string RaidType { get; set; } 30  [Required] 31         [DisplayName("硬盤個數")] 32         public int HDDNum { get; set; } 33  [Required] 34         [DisplayName("機箱型號")] 35         public string CaseType { get; set; } 36  } 37 }
ServersUsing
 1 using System;  2 using System.Collections.Generic;  3 using System.ComponentModel;  4 using System.ComponentModel.DataAnnotations;  5 using System.Linq;  6 using System.Web;  7 
 8 namespace monitoring.Models  9 { 10     public class NIC 11  { 12         public int ID { get; set; } 13         public string AMDCDkey { get; set; } 14  [Required] 15         [DisplayName("網卡型號")] 16         public string NICType { get; set; } 17  [Required] 18         [DisplayName("網卡數量")] 19         public int NICNum { get; set; } 20  } 21 }
NIC
 1 using System;  2 using System.Collections.Generic;  3 using System.ComponentModel;  4 using System.ComponentModel.DataAnnotations;  5 using System.Linq;  6 using System.Web;  7 
 8 namespace monitoring.Models  9 { 10     public class HDD 11  { 12         public int ID { get; set; } 13         public string AMDCDkey { get; set; } 14         public int RootHDD { get; set; } 15  [Required] 16         [DisplayName("硬盤標識")] 17         public string HDDID { get; set; } 18  [Required] 19         [DisplayName("硬盤型號")] 20         public string HDDType { get; set; } 21  [Required] 22         [DisplayName("硬盤容量")] 23         public string HDDCap { get; set; } 24  } 25 }
HDD

爲了將多Model傳到View層,單獨創建一個List,將多個model的信息添加到List中。架構

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 
 6 namespace monitoring.Models  7 {  8     public class ViewModel  9  { 10         public int ID { get; set; } 11         public Servers SView { get; set; } 12         public ServersUsing SUView { get; set; } 13         public List<NIC> NICView { get; set; } 14         public List<HDD> HDDView { get; set; } 15  } 16 }
ViewModel

如需實現,還要有上下文:框架

 1 using System.Data.Entity;  2 
 3 namespace monitoring.Models  4 {  5     public class ServersContext : DbContext  6  {  7         // 您能夠向此文件中添加自定義代碼。更改不會被覆蓋。  8         // 
 9         // 若是您但願只要更改模型架構,Entity Framework 10         // 就會自動刪除並從新生成數據庫,則將如下 11         // 代碼添加到 Global.asax 文件中的 Application_Start 方法。 12         // 注意: 這將在每次更改模型時銷燬並從新建立數據庫。 13         // 
14         // System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<monitoring.Models.ServersContext>());
15 
16         public ServersContext() : base("name=ServersContext") 17  { 18 
19  } 20 
21         public DbSet<Servers> Servers { get; set; } 22         public DbSet<ServersUsing> ServersUsings { get; set; } 23         public DbSet<NIC> NICs { get; set; } 24         public DbSet<HDD> HDDs { get; set; } 25  } 26 }
ServerContext

Controller層:ide

實現瞭解析Json並添加數據庫的方法,實現了查詢和分頁功能,完成了將多Model傳到View層的方法。

 1 using System;  2 using System.Collections.Generic;  3 using System.Data;  4 using System.Data.Entity;  5 using System.Linq;  6 using System.Web;  7 using System.Web.Mvc;  8 using monitoring.Models;  9 using Newtonsoft.Json.Linq;  10 using Newtonsoft.Json;  11 using System.IO;  12 using monitoring.Controllers;  13 using System.Web.Script.Serialization;  14 using PagedList;  15 
 16 namespace monitoring.Controllers  17 {  18     public class ServersController : Controller  19  {  20         private ServersContext db = new ServersContext();  21         public void ParseJson(StreamReader reader)  22  {  23             // 配置信息
 24             JToken jobject = JToken.ReadFrom(new JsonTextReader(reader));  25             string jsonText = jobject.ToString();  26             JObject roots = (JObject)JsonConvert.DeserializeObject(jsonText);  27             JArray servers = (JArray)roots["Servers"];  28             for (int i = 0; i < servers.Count; i++)  29  {  30                 JObject root = (JObject)servers[i];  31                 Servers newdate = new Servers();  32                 newdate.AMDCDkey = (string)root["AMDCDkey"];  33                 newdate.HostName = (string)root["HostName"];  34                 newdate.CPUType = (string)root["CPUType"];  35                 newdate.CPUNum = (int)root["CPUNum"];  36                 newdate.RAMSize = (string)root["RAMSize"];  37                 newdate.RaidType = (string)root["RaidType"];  38                 newdate.HDDNum = (int)root["HDDNum"];  39                 newdate.CaseType = (string)root["CaseType"];  40                 bool NewDate = false;  41                 try
 42  {  43                     var server = db.Servers.Single(x => x.AMDCDkey == newdate.AMDCDkey);  44                     if (server != newdate)  45  {  46                         server = newdate;  47                         UpdateModel<Servers>(newdate);  48  db.SaveChanges();  49  }  50  }  51                 catch
 52  {  53                     NewDate = true;  54  db.Servers.Add(newdate);  55  db.SaveChanges();  56  }  57 
 58                 // 運行狀態信息
 59                 ServersUsing newdateusi = new ServersUsing();  60                 newdateusi.AMDCDkey = (string)root["AMDCDkey"];  61                 newdateusi.CPUUsRate = (string)root["CPUUsRate"];  62                 newdateusi.RAMUsRate = (string)root["RAMUsRate"];  63                 newdateusi.HDDUsRate = (string)root["HDDUsRate"];  64                 newdateusi.HDDIO = (string)root["HDDIO"];  65                 newdateusi.HostcomputerLoad = (string)root["HostcomputerLoad"];  66                 newdateusi.TheRootPartitionUsageRate = (string)root["TheRootPartitionUsageRate"];  67                 newdateusi.Time = DateTime.Now;  68  db.ServersUsings.Add(newdateusi);  69  db.SaveChanges();  70 
 71                 // 網卡信息
 72                 JArray NICs = (JArray)root["NIC"];  73                 if (NewDate == true)  74  {  75                     for (int b = 0; b < NICs.Count; b++)  76  {  77                         JObject nics = (JObject)NICs[b];  78                         NIC newdatenic = new NIC();  79                         newdatenic.AMDCDkey = (string)root["AMDCDkey"];  80                         newdatenic.NICType = (string)nics["NICType"];  81                         newdatenic.NICNum = (int)nics["NICNum"];  82  db.NICs.Add(newdatenic);  83  db.SaveChanges();  84  }  85  }  86                 else
 87  {  88                     JavaScriptSerializer Serializer = new JavaScriptSerializer();  89                     List<NIC> objs = Serializer.Deserialize<List<NIC>>(NICs.ToString());  90                     List<NIC> nic = db.NICs.Where(x => x.AMDCDkey == newdate.AMDCDkey).ToList();  91                     bool b = false;  92                     foreach (var a in nic) { if (!objs.Contains(a)) b = true; }  93                     if (b && nic.Count != objs.Count)  94  {  95                         var remove = db.NICs.Where(x => x.AMDCDkey == newdate.AMDCDkey);  96                         foreach (var a in remove)  97  {  98  db.NICs.Remove(a);  99  } 100                         for (int d = 0; d < NICs.Count; d++) 101  { 102                             JObject nics = (JObject)NICs[d]; 103                             NIC newdatenic = new NIC(); 104                             newdatenic.AMDCDkey = (string)root["AMDCDkey"]; 105                             newdatenic.NICType = (string)nics["NICType"]; 106                             newdatenic.NICNum = (int)nics["NICNum"]; 107  db.NICs.Add(newdatenic); 108  } 109  db.SaveChanges(); 110  } 111  } 112 
113                 // 硬盤信息
114                 JArray HDDs = (JArray)root["HDD"]; 115 
116                 if (NewDate == true) 117  { 118                     for (int f = 0; f < HDDs.Count; f++) 119  { 120                         JObject hdds = (JObject)HDDs[f]; 121                         HDD newdatehdd = new HDD(); 122                         newdatehdd.HDDID = (string)hdds["HDDID"]; 123                         newdatehdd.RootHDD = (int)hdds["RootHDD"]; 124                         newdatehdd.AMDCDkey = (string)root["AMDCDkey"]; 125                         newdatehdd.HDDType = (string)hdds["HDDType"]; 126                         newdatehdd.HDDCap = (string)hdds["HDDCap"]; 127  db.HDDs.Add(newdatehdd); 128  db.SaveChanges(); 129  } 130  } 131                 else
132  { 133                     JavaScriptSerializer Serializer = new JavaScriptSerializer(); 134                     List<HDD> objs = Serializer.Deserialize<List<HDD>>(HDDs.ToString()); 135                     List<HDD> hdd = db.HDDs.Where(x => x.AMDCDkey == newdate.AMDCDkey).ToList(); 136                     bool b = false; 137                     foreach (var a in hdd) { if (!objs.Contains(a)) b = true; } 138                     if (b && hdd.Count != objs.Count) 139  { 140                         var remove = db.HDDs.Where(x => x.AMDCDkey == newdate.AMDCDkey); 141                         foreach (var a in remove) 142  { 143  db.HDDs.Remove(a); 144  } 145                         for (int f = 0; f < HDDs.Count; f++) 146  { 147                             JObject hdds = (JObject)HDDs[f]; 148                             HDD newdatehdd = new HDD(); 149                             newdatehdd.HDDID = (string)hdds["HDDID"]; 150                             newdatehdd.RootHDD = (int)hdds["RootHDD"]; 151                             newdatehdd.AMDCDkey = (string)root["AMDCDkey"]; 152                             newdatehdd.HDDType = (string)hdds["HDDType"]; 153                             newdatehdd.HDDCap = (string)hdds["HDDCap"]; 154  db.HDDs.Add(newdatehdd); 155  } 156  db.SaveChanges(); 157  } 158  } 159  } 160  } 161         public ActionResult Index(string searchString, int? page) 162  { 163             // 遍歷文件夾中的文件 164             //string path = "C:\\Users\\edong\\Desktop\\json"; 165             //DirectoryInfo dir = new DirectoryInfo(path); 166             //FileInfo[] fil = dir.GetFiles(); 167             //foreach (FileInfo f in fil) 168             //{ 169             // using (StreamReader reader = System.IO.File.OpenText("" + f.FullName + "")) 170             // { 171             // ParseJson(reader); 172             // } 173             //    // 存入數據庫後刪除json文件 174             //    // System.IO.File.Delete(@""+ f.FullName +""); 175             //}
176             int pageNumber = page ?? 1; 177 
178             var servers = db.Servers.OrderByDescending(e => e.ID); 179 
180             var listallview = new List<ViewModel>(); 181             foreach (var s in servers) 182  { 183                 listallview.Add(new ViewModel() 184  { 185                     SView = s, 186                     SUView = db.ServersUsings.Where(o => o.AMDCDkey == s.AMDCDkey).First(), 187                     NICView = db.NICs.Where(o => o.AMDCDkey == s.AMDCDkey).ToList(), 188                     HDDView = db.HDDs.Where(o => o.AMDCDkey == s.AMDCDkey).ToList() 189  }); 190  } 191             var pagelist = listallview.OrderByDescending(e => e.ID).ToPagedList(pageNumber, 7); 192             // 查詢
193             if (!string.IsNullOrEmpty(searchString)) 194  { 195                 pagelist = listallview.Where(s => s.SView.HostName.Contains(searchString)).ToPagedList(pageNumber, 7); 196  } 197             // 服務器網卡/硬盤數量最大值
198             int NICNum = 0; 199             int HDDNum = 0; 200             foreach (var item in pagelist) 201  { 202                 if (NICNum < item.NICView.Count) 203                     NICNum = item.NICView.Count; 204                 if (HDDNum < item.HDDView.Count) 205                     HDDNum = item.HDDView.Count; 206  } 207             ViewBag.NICNum = NICNum; 208             ViewBag.HDDNum = HDDNum; 209 
210             return View(pagelist); 211  } 212 
213         protected override void Dispose(bool disposing) 214  { 215  db.Dispose(); 216             base.Dispose(disposing); 217  } 218  } 219 }
ServersController

View層:

爲了方便查看View和Controller中的傳值等問題,先貼代碼再貼圖。(View中引用了Bootstrap,UI同事教了我一點,僅做排版使用。)

 1 @using monitoring.Models;  2 @using PagedList.Mvc;  3 
 4 @model PagedList.PagedList<ViewModel>
 5 
 6 @{  7     ViewBag.Title = "Index";  8 }  9 <!DOCTYPE html>
 10 <head>
 11     <title>服務器設備配置信息</title>
 12     @*自動刷新,間隔10s*@  13     @*<meta http-equiv="REFRESH" content="10">*@  14     <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
 15     <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
 16 
 17     <!-- 可選的 Bootstrap 主題文件(通常不用引入) -->
 18     <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
 19     <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
 20 
 21     <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
 22     <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
 23 </head>
 24 <style type="text/css">
 25  .Menu {  26         float: left;  27  background: #ffffff;  28  }  29 
 30  .Menu li {  31  margin: 30px 40px 30px 0px;  32             list-style: none;  33             text-align: center;  34  }  35 
 36  .Table {  37  background: #4ba54b;  38  color: #ffffff;  39         border-radius: 50px;  40  }  41 
 42  .Date {  43  background: #ffffff;  44  width: 1150px;  45         float: left;  46  margin: 0px 0px 10px 20px;  47  }  48 
 49  .Date ul {  50  width: 160px;  51             float: left;  52  }  53 
 54  .Date ul li {  55  margin: 30px 0px 30px 0px;  56                 text-align: center;  57                 list-style: none;  58  }  59 
 60  .Text {  61  width: 378px;  62  height: 40px;  63         float: left;  64  margin: 12px 0px 0px 5px;  65  background: #efefef;  66         padding-left: 15px;  67         border-radius: 42px;  68  border: 2px solid #efefef;  69  outline: none;  70  position: absolute;  71  }  72 
 73  .search {  74  position: absolute;  75         top: 0;  76         right: 0;  77  width: 42px;  78  height: 42px;  79  background: none;  80  border: none;  81         right: 0;  82         margin-top: 12px;  83  }  84 </style>
 85 <body style="background:#efefef">
 86     <div style="width:1500px">
 87         <div style="margin: 30px 0px 0px 60px; box-shadow: #ff0000 0px 0px 10px; ">
 88             <ul class="Menu">
 89                 <li class="Table">配置</li>
 90                 <li>主機名</li>
 91                 <li>CPU型號</li>
 92                 <li>CPU數量</li>
 93                 <li>內存大小</li>
 94                 <li>Raid卡型號</li>
 95                 <li>硬盤個數</li>
 96                 <li>機箱型號</li>
 97                 <li class="Table">運行狀態</li>
 98                 <li>CPU使用率</li>
 99                 <li>內存使用率</li>
100                 <li>硬盤使用率</li>
101                 <li>硬盤I/O</li>
102                 <li>主機負載</li>
103                 <li>根分區使用率</li>
104                 <li>時間</li>
105                 <li class="Table">網卡信息</li>
106                 @for (int i = 0; i < ViewBag.NICNum; i++) 107  { 108                     <li>網卡型號</li>
109                     <li>網卡數量</li>
110  } 111                 <li class="Table">硬盤信息</li>
112                 <li>根硬盤型號</li>
113                 <li>根硬盤容量</li>
114                 @for (int i = 1; i < ViewBag.HDDNum; i++) 115  { 116                     <li>硬盤型號</li>
117                     <li>硬盤容量</li>
118  } 119             </ul>
120         </div>
121         <div class="Date clearfix" style="height:65px">
122             @using (Html.BeginForm("Index", "Servers", FormMethod.Get)) 123  { 124                 <div class="row">
125                     <div class="col-sm-4" style="float:left">
126                         <form class="form">
127                             <div class="form-group">
128                                 @Html.TextBox("SearchString", null, new { @class = "form-control Text", placeholder = "主機名" }) 129                                 <button type="submit" class="search"><span class="glyphicon glyphicon-search"></span></button>
130                             </div>
131                         </form>
132                     </div>
133                     <div class="col-sm-8" style="float:right">@Html.PagedListPager(Model, page => Url.Action("Index", new { page }))</div>
134                 </div>
135  } 136         </div>
137         <div class="Date">
138             @foreach (var item in Model) 139  { 140                 <ul>
141                     <li style="margin: 5px 0px 30px 0px">@item.SView.HostName</li>
142                     <li>@item.SView.CPUType</li>
143                     <li>@item.SView.CPUNum</li>
144                     <li>@item.SView.RAMSize</li>
145                     <li>@item.SView.RaidType</li>
146                     <li>@item.SView.HDDNum</li>
147                     <li style="margin: 30px 0px 5px 0px">@item.SView.CaseType</li>
148                 </ul>
149  } 150         </div>
151         <div class="Date" style="margin:30px 0px 10px 20px;">
152             @foreach (var item in Model) 153  { 154                 <ul>
155                     <li style="margin: 25px 0px 30px 0px">@item.SUView.CPUUsRate</li>
156                     <li>@item.SUView.RAMUsRate</li>
157                     <li>@item.SUView.HDDUsRate</li>
158                     <li>@item.SUView.HDDIO</li>
159                     <li>@item.SUView.HostcomputerLoad</li>
160                     <li>@item.SUView.TheRootPartitionUsageRate</li>
161                     <li style="margin: 30px 0px 5px 0px">@item.SUView.Time</li>
162                 </ul>
163  } 164         </div>
165         <div class="Date" style="margin: 25px 0px 10px 20px;">
166             @foreach (var item in Model) 167  { 168                 <ul>
169                     @foreach (var item1 in @item.NICView) 170  { 171                         <li>@item1.NICType</li>
172                         <li style="margin: 30px 0px 10px 0px">@item1.NICNum</li>
173  } 174                 </ul>
175  } 176         </div>
177         <div class="Date" style="margin:15px 0px 10px 20px;">
178             @foreach (var item in Model) 179  { 180                 <ul>
181                     @foreach (var item2 in @item.HDDView) 182  { 183                         if (item2.RootHDD == 1) 184  { 185                             <li>@item2.HDDType</li>
186                             <li>@item2.HDDCap</li>
187  } 188  } 189                     @foreach (var item2 in @item.HDDView) 190  { 191                         if (item2.RootHDD != 1) 192  { 193                             <li>@item2.HDDType</li>
194                             <li>@item2.HDDCap</li>
195  } 196  } 197                 </ul>
198  } 199         </div>
200     </div>
201 </body>
View

再將設計老王給的圖貼一下。

評價:豎版排版很好的解決了服務器屬性過多,須要顯示多條數據的問題,也解決了每一個服務器須要展現多個網卡數據和硬盤數據的問題。可是並無解決根本的問題,硬盤上限44,某個服務器可能搭載了44個硬盤,若是所有展現出來則頁面太長。

View層完成圖:

經理看後提了好多改進的方式,包括Model的命名不規範,數據庫中使用無心義的主鍵的原則,Model中主鍵外鍵的設置。Controller中Json數據能夠直接轉成model中的類型。以及View界面過長改進思路的問題。

此爲畢業後的第一個程序,把初版的代碼保留下來,接下來進行代碼的重構。

相關文章
相關標籤/搜索