MVC框架json数据展示程序(第一版)
模型原型:服务器的配置和运行状态信息。
设计要求:Json格式数据解析后,判断配置信息是否是新数据或者是否更新。如是新数据,则直接添加到数据库;若是数据更新,则更新数据库配置信息并更新运行状态信息;都不是则仅将运行状态添加到数据库。最后从数据库取数据并展示。
模型难点:每个服务器会搭载多个网卡和最多44个硬盘。
(1)View层如何同时展示所有硬盘和其他设备属性的信息。
(2)单服务器配多网卡多硬盘必定会设计多个表(即服务器配置表、运行状态表、网卡配置表、硬盘配置表),MVC框架下如何同时将其Model传到View层。
(3)本文程序使用PageList进行分页,通常为了程序运行速度,会在查询时进行分页,及var servers = db.Servers.OrderByDescending(e => e.ID).ToPagedList(pageNumber, 7),但本设计考虑到多Model传到View层,此方法不适用。如何使程序适应上万条数据的数据库。
Model层:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web; namespace monitoring.Models
{
public class Servers
{
public int ID { get; set; }
[Required]
[DisplayName("主板序列号")]
public string AMDCDkey { get; set; }
[Required]
[DisplayName("服务器名")]
public string HostName { get; set; }
[Required]
[DisplayName("CPU型号")]
public string CPUType { get; set; }
[Required]
[DisplayName("CPU数量")]
public int CPUNum { get; set; }
[Required]
[DisplayName("内存大小")]
public string RAMSize { get; set; }
[DisplayName("Raid卡型号")]
public string RaidType { get; set; }
[Required]
[DisplayName("硬盘个数")]
public int HDDNum { get; set; }
[Required]
[DisplayName("机箱型号")]
public string CaseType { get; set; }
}
}
Servers
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web; namespace monitoring.Models
{
public class Servers
{
public int ID { get; set; }
[Required]
[DisplayName("主板序列号")]
public string AMDCDkey { get; set; }
[Required]
[DisplayName("服务器名")]
public string HostName { get; set; }
[Required]
[DisplayName("CPU型号")]
public string CPUType { get; set; }
[Required]
[DisplayName("CPU数量")]
public int CPUNum { get; set; }
[Required]
[DisplayName("内存大小")]
public string RAMSize { get; set; }
[DisplayName("Raid卡型号")]
public string RaidType { get; set; }
[Required]
[DisplayName("硬盘个数")]
public int HDDNum { get; set; }
[Required]
[DisplayName("机箱型号")]
public string CaseType { get; set; }
}
}
ServersUsing
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web; namespace monitoring.Models
{
public class NIC
{
public int ID { get; set; }
public string AMDCDkey { get; set; }
[Required]
[DisplayName("网卡型号")]
public string NICType { get; set; }
[Required]
[DisplayName("网卡数量")]
public int NICNum { get; set; }
}
}
NIC
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web; namespace monitoring.Models
{
public class HDD
{
public int ID { get; set; }
public string AMDCDkey { get; set; }
public int RootHDD { get; set; }
[Required]
[DisplayName("硬盘标识")]
public string HDDID { get; set; }
[Required]
[DisplayName("硬盘型号")]
public string HDDType { get; set; }
[Required]
[DisplayName("硬盘容量")]
public string HDDCap { get; set; }
}
}
HDD
为了将多Model传到View层,单独建立一个List,将多个model的信息添加到List中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace monitoring.Models
{
public class ViewModel
{
public int ID { get; set; }
public Servers SView { get; set; }
public ServersUsing SUView { get; set; }
public List<NIC> NICView { get; set; }
public List<HDD> HDDView { get; set; }
}
}
ViewModel
如需实现,还要有上下文:
using System.Data.Entity; namespace monitoring.Models
{
public class ServersContext : DbContext
{
// 您可以向此文件中添加自定义代码。更改不会被覆盖。
//
// 如果您希望只要更改模型架构,Entity Framework
// 就会自动删除并重新生成数据库,则将以下
// 代码添加到 Global.asax 文件中的 Application_Start 方法。
// 注意: 这将在每次更改模型时销毁并重新创建数据库。
//
// System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges<monitoring.Models.ServersContext>()); public ServersContext() : base("name=ServersContext")
{ } public DbSet<Servers> Servers { get; set; }
public DbSet<ServersUsing> ServersUsings { get; set; }
public DbSet<NIC> NICs { get; set; }
public DbSet<HDD> HDDs { get; set; }
}
}
ServerContext
Controller层:
实现了解析Json并添加数据库的方法,实现了查询和分页功能,完成了将多Model传到View层的方法。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using monitoring.Models;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.IO;
using monitoring.Controllers;
using System.Web.Script.Serialization;
using PagedList; namespace monitoring.Controllers
{
public class ServersController : Controller
{
private ServersContext db = new ServersContext();
public void ParseJson(StreamReader reader)
{
// 配置信息
JToken jobject = JToken.ReadFrom(new JsonTextReader(reader));
string jsonText = jobject.ToString();
JObject roots = (JObject)JsonConvert.DeserializeObject(jsonText);
JArray servers = (JArray)roots["Servers"];
for (int i = ; i < servers.Count; i++)
{
JObject root = (JObject)servers[i];
Servers newdate = new Servers();
newdate.AMDCDkey = (string)root["AMDCDkey"];
newdate.HostName = (string)root["HostName"];
newdate.CPUType = (string)root["CPUType"];
newdate.CPUNum = (int)root["CPUNum"];
newdate.RAMSize = (string)root["RAMSize"];
newdate.RaidType = (string)root["RaidType"];
newdate.HDDNum = (int)root["HDDNum"];
newdate.CaseType = (string)root["CaseType"];
bool NewDate = false;
try
{
var server = db.Servers.Single(x => x.AMDCDkey == newdate.AMDCDkey);
if (server != newdate)
{
server = newdate;
UpdateModel<Servers>(newdate);
db.SaveChanges();
}
}
catch
{
NewDate = true;
db.Servers.Add(newdate);
db.SaveChanges();
} // 运行状态信息
ServersUsing newdateusi = new ServersUsing();
newdateusi.AMDCDkey = (string)root["AMDCDkey"];
newdateusi.CPUUsRate = (string)root["CPUUsRate"];
newdateusi.RAMUsRate = (string)root["RAMUsRate"];
newdateusi.HDDUsRate = (string)root["HDDUsRate"];
newdateusi.HDDIO = (string)root["HDDIO"];
newdateusi.HostcomputerLoad = (string)root["HostcomputerLoad"];
newdateusi.TheRootPartitionUsageRate = (string)root["TheRootPartitionUsageRate"];
newdateusi.Time = DateTime.Now;
db.ServersUsings.Add(newdateusi);
db.SaveChanges(); // 网卡信息
JArray NICs = (JArray)root["NIC"];
if (NewDate == true)
{
for (int b = ; b < NICs.Count; b++)
{
JObject nics = (JObject)NICs[b];
NIC newdatenic = new NIC();
newdatenic.AMDCDkey = (string)root["AMDCDkey"];
newdatenic.NICType = (string)nics["NICType"];
newdatenic.NICNum = (int)nics["NICNum"];
db.NICs.Add(newdatenic);
db.SaveChanges();
}
}
else
{
JavaScriptSerializer Serializer = new JavaScriptSerializer();
List<NIC> objs = Serializer.Deserialize<List<NIC>>(NICs.ToString());
List<NIC> nic = db.NICs.Where(x => x.AMDCDkey == newdate.AMDCDkey).ToList();
bool b = false;
foreach (var a in nic) { if (!objs.Contains(a)) b = true; }
if (b && nic.Count != objs.Count)
{
var remove = db.NICs.Where(x => x.AMDCDkey == newdate.AMDCDkey);
foreach (var a in remove)
{
db.NICs.Remove(a);
}
for (int d = ; d < NICs.Count; d++)
{
JObject nics = (JObject)NICs[d];
NIC newdatenic = new NIC();
newdatenic.AMDCDkey = (string)root["AMDCDkey"];
newdatenic.NICType = (string)nics["NICType"];
newdatenic.NICNum = (int)nics["NICNum"];
db.NICs.Add(newdatenic);
}
db.SaveChanges();
}
} // 硬盘信息
JArray HDDs = (JArray)root["HDD"]; if (NewDate == true)
{
for (int f = ; f < HDDs.Count; f++)
{
JObject hdds = (JObject)HDDs[f];
HDD newdatehdd = new HDD();
newdatehdd.HDDID = (string)hdds["HDDID"];
newdatehdd.RootHDD = (int)hdds["RootHDD"];
newdatehdd.AMDCDkey = (string)root["AMDCDkey"];
newdatehdd.HDDType = (string)hdds["HDDType"];
newdatehdd.HDDCap = (string)hdds["HDDCap"];
db.HDDs.Add(newdatehdd);
db.SaveChanges();
}
}
else
{
JavaScriptSerializer Serializer = new JavaScriptSerializer();
List<HDD> objs = Serializer.Deserialize<List<HDD>>(HDDs.ToString());
List<HDD> hdd = db.HDDs.Where(x => x.AMDCDkey == newdate.AMDCDkey).ToList();
bool b = false;
foreach (var a in hdd) { if (!objs.Contains(a)) b = true; }
if (b && hdd.Count != objs.Count)
{
var remove = db.HDDs.Where(x => x.AMDCDkey == newdate.AMDCDkey);
foreach (var a in remove)
{
db.HDDs.Remove(a);
}
for (int f = ; f < HDDs.Count; f++)
{
JObject hdds = (JObject)HDDs[f];
HDD newdatehdd = new HDD();
newdatehdd.HDDID = (string)hdds["HDDID"];
newdatehdd.RootHDD = (int)hdds["RootHDD"];
newdatehdd.AMDCDkey = (string)root["AMDCDkey"];
newdatehdd.HDDType = (string)hdds["HDDType"];
newdatehdd.HDDCap = (string)hdds["HDDCap"];
db.HDDs.Add(newdatehdd);
}
db.SaveChanges();
}
}
}
}
public ActionResult Index(string searchString, int? page)
{
// 遍历文件夹中的文件
//string path = "C:\\Users\\edong\\Desktop\\json";
//DirectoryInfo dir = new DirectoryInfo(path);
//FileInfo[] fil = dir.GetFiles();
//foreach (FileInfo f in fil)
//{
// using (StreamReader reader = System.IO.File.OpenText("" + f.FullName + ""))
// {
// ParseJson(reader);
// }
// // 存入数据库后删除json文件
// // System.IO.File.Delete(@""+ f.FullName +"");
//}
int pageNumber = page ?? ; var servers = db.Servers.OrderByDescending(e => e.ID); var listallview = new List<ViewModel>();
foreach (var s in servers)
{
listallview.Add(new ViewModel()
{
SView = s,
SUView = db.ServersUsings.Where(o => o.AMDCDkey == s.AMDCDkey).First(),
NICView = db.NICs.Where(o => o.AMDCDkey == s.AMDCDkey).ToList(),
HDDView = db.HDDs.Where(o => o.AMDCDkey == s.AMDCDkey).ToList()
});
}
var pagelist = listallview.OrderByDescending(e => e.ID).ToPagedList(pageNumber, );
// 查询
if (!string.IsNullOrEmpty(searchString))
{
pagelist = listallview.Where(s => s.SView.HostName.Contains(searchString)).ToPagedList(pageNumber, );
}
// 服务器网卡/硬盘数量最大值
int NICNum = ;
int HDDNum = ;
foreach (var item in pagelist)
{
if (NICNum < item.NICView.Count)
NICNum = item.NICView.Count;
if (HDDNum < item.HDDView.Count)
HDDNum = item.HDDView.Count;
}
ViewBag.NICNum = NICNum;
ViewBag.HDDNum = HDDNum; return View(pagelist);
} protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
ServersController
View层:
为了方便查看View和Controller中的传值等问题,先贴代码再贴图。(View中引用了Bootstrap,UI同事教了我一点,仅作排版使用。)
@using monitoring.Models;
@using PagedList.Mvc; @model PagedList.PagedList<ViewModel> @{
ViewBag.Title = "Index";
}
<!DOCTYPE html>
<head>
<title>服务器设备配置信息</title>
@*自动刷新,间隔10s*@
@*<meta http-equiv="REFRESH" content="">*@
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<style type="text/css">
.Menu {
float: left;
background: #ffffff;
} .Menu li {
margin: 30px 40px 30px 0px;
list-style: none;
text-align: center;
} .Table {
background: #4ba54b;
color: #ffffff;
border-radius: 50px;
} .Date {
background: #ffffff;
width: 1150px;
float: left;
margin: 0px 0px 10px 20px;
} .Date ul {
width: 160px;
float: left;
} .Date ul li {
margin: 30px 0px 30px 0px;
text-align: center;
list-style: none;
} .Text {
width: 378px;
height: 40px;
float: left;
margin: 12px 0px 0px 5px;
background: #efefef;
padding-left: 15px;
border-radius: 42px;
border: 2px solid #efefef;
outline: none;
position: absolute;
} .search {
position: absolute;
top: ;
right: ;
width: 42px;
height: 42px;
background: none;
border: none;
right: ;
margin-top: 12px;
}
</style>
<body style="background:#efefef">
<div style="width:1500px">
<div style="margin: 30px 0px 0px 60px; box-shadow: #ff0000 0px 0px 10px; ">
<ul class="Menu">
<li class="Table">配置</li>
<li>主机名</li>
<li>CPU型号</li>
<li>CPU数量</li>
<li>内存大小</li>
<li>Raid卡型号</li>
<li>硬盘个数</li>
<li>机箱型号</li>
<li class="Table">运行状态</li>
<li>CPU使用率</li>
<li>内存使用率</li>
<li>硬盘使用率</li>
<li>硬盘I/O</li>
<li>主机负载</li>
<li>根分区使用率</li>
<li>时间</li>
<li class="Table">网卡信息</li>
@for (int i = ; i < ViewBag.NICNum; i++)
{
<li>网卡型号</li>
<li>网卡数量</li>
}
<li class="Table">硬盘信息</li>
<li>根硬盘型号</li>
<li>根硬盘容量</li>
@for (int i = ; i < ViewBag.HDDNum; i++)
{
<li>硬盘型号</li>
<li>硬盘容量</li>
}
</ul>
</div>
<div class="Date clearfix" style="height:65px">
@using (Html.BeginForm("Index", "Servers", FormMethod.Get))
{
<div class="row">
<div class="col-sm-4" style="float:left">
<form class="form">
<div class="form-group">
@Html.TextBox("SearchString", null, new { @class = "form-control Text", placeholder = "主机名" })
<button type="submit" class="search"><span class="glyphicon glyphicon-search"></span></button>
</div>
</form>
</div>
<div class="col-sm-8" style="float:right">@Html.PagedListPager(Model, page => Url.Action("Index", new { page }))</div>
</div>
}
</div>
<div class="Date">
@foreach (var item in Model)
{
<ul>
<li style="margin: 5px 0px 30px 0px">@item.SView.HostName</li>
<li>@item.SView.CPUType</li>
<li>@item.SView.CPUNum</li>
<li>@item.SView.RAMSize</li>
<li>@item.SView.RaidType</li>
<li>@item.SView.HDDNum</li>
<li style="margin: 30px 0px 5px 0px">@item.SView.CaseType</li>
</ul>
}
</div>
<div class="Date" style="margin:30px 0px 10px 20px;">
@foreach (var item in Model)
{
<ul>
<li style="margin: 25px 0px 30px 0px">@item.SUView.CPUUsRate</li>
<li>@item.SUView.RAMUsRate</li>
<li>@item.SUView.HDDUsRate</li>
<li>@item.SUView.HDDIO</li>
<li>@item.SUView.HostcomputerLoad</li>
<li>@item.SUView.TheRootPartitionUsageRate</li>
<li style="margin: 30px 0px 5px 0px">@item.SUView.Time</li>
</ul>
}
</div>
<div class="Date" style="margin: 25px 0px 10px 20px;">
@foreach (var item in Model)
{
<ul>
@foreach (var item1 in @item.NICView)
{
<li>@item1.NICType</li>
<li style="margin: 30px 0px 10px 0px">@item1.NICNum</li>
}
</ul>
}
</div>
<div class="Date" style="margin:15px 0px 10px 20px;">
@foreach (var item in Model)
{
<ul>
@foreach (var item2 in @item.HDDView)
{
if (item2.RootHDD == )
{
<li>@item2.HDDType</li>
<li>@item2.HDDCap</li>
}
}
@foreach (var item2 in @item.HDDView)
{
if (item2.RootHDD != )
{
<li>@item2.HDDType</li>
<li>@item2.HDDCap</li>
}
}
</ul>
}
</div>
</div>
</body>
View
再将设计老王给的图贴一下。
评价:竖版排版很好的解决了服务器属性过多,需要显示多条数据的问题,也解决了每个服务器需要展示多个网卡数据和硬盘数据的问题。但是并没有解决根本的问题,硬盘上限44,某个服务器可能搭载了44个硬盘,如果全部展示出来则页面太长。
View层完成图:
经理看后提了好多改进的方式,包括Model的命名不规范,数据库中使用无意义的主键的原则,Model中主键外键的设置。Controller中Json数据可以直接转成model中的类型。以及View界面过长改进思路的问题。
此为毕业后的第一个程序,把第一版的代码保留下来,接下来进行代码的重构。
MVC框架json数据展示程序(第一版)的更多相关文章
- ajax使用向Spring MVC发送JSON数据出现 org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported错误
ajax使用向Spring MVC发送JSON数据时,后端Controller在接受JSON数据时报org.springframework.web.HttpMediaTypeNotSupportedE ...
- Spring MVC返回json数据给Android端
原先做Android项目时,服务端接口一直是别人写的,自己拿来调用一下,但下个项目,接口也要自己搞定了,我想用Spring MVC框架来提供接口,这两天便抽空浅学了一下该框架以及该框架如何返回json ...
- Spring MVC生成JSON数据
以下示例演示如何使用Spring Web MVC框架生成JSON数据格式.首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: ...
- 调取jSon数据--展示
下面代码是将页面中的展示部分 function searchProductlistByfilterCondition(index, type, sort, filterWord) { //cite_h ...
- ArcGIS Server 10.2 实战(一)Asp.net MVC与JSON数据妙用实现动态生成要素图层
今年7月刚刚发布的ArcGIS 10.2为GIS的web开发带来了一个很实在的功能,JSON转要素.以往GIS图层外部数据(如文本数据,数据库数据)动态地写入地图服务中的图层是一件不可想象的事情,如今 ...
- JSON数据展示神器:react-json-view(常用于后台网站)
一.react-json-view - npm 官方定义: RJV is a React component for displaying and editing javascript arrays ...
- Spring MVC之JSON数据交互和RESTful的支持
1.JSON概述 1.1 什么是JSON JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式.它是基于JavaScript的一个子集,使用了C.C ...
- ES6_Demo,模拟后台json数据展示
最近在学习ES6,下面,模拟后台传过来json数据,并在页面展示的一个小Demo. 页面简单的不可描述,只有一个button按钮 <button>点击获取json数据</button ...
- spring mvc 返回json数据的四种方式
一.返回ModelAndView,其中包含map集 /* * 返回ModelAndView类型的结果 * 检查用户名的合法性,如果用户已经存在,返回false,否则返回true(返回json数据,格式 ...
随机推荐
- 如何从平面设计转行到UI设计?
时代的变迁,科技的进步,工具的发展,薪资的差距,促使许多人转行的原因,但平面与界面两者之间有着哪些的差异呢?如果,想要转行又该具备哪些条件呢? 平面.界面设计之间的差异性 平面设计以『视觉』为主轴,强 ...
- DOM-查找和修改
1. 查找: 按HTML查找: 问题: 每次只能按一个条件查找,如果查找条件复杂,则步骤很繁琐 解决: 选择器: 按选择器查找: 2个API 1. 只查找一个元素: var elem=parent.q ...
- tensorflow下识别手写数字基于MLP网络
# coding: utf-8 # In[1]: import tensorflow as tf import tensorflow.examples.tutorials.mnist.input_da ...
- centos7 hbase 搭建笔记
1.require:java环境,本地可用的hadoop 2.拷贝hbase文件(hive-1.2.6) 3.设置环境变量 export HBASE_HOME=/data/spark/bin/hbas ...
- centos 7 禁止root登录及更改ssh端口号
vim /etc/ssh/sshd_config PermitRootLogin yes => PermitRootLogin no systemctl restart sshd.service ...
- pt-query-digest详解慢查询日志
一.简介 pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdu ...
- Win7 VS2015及MinGW环境编译FFMPEG-20160326
因为又要弄MinGW了,所以顺便把FFMPEG编译了,文章主要参考这篇,防抽所以复制一遍,顺便加些自己的内容 http://blog.csdn.net/finewind/article/details ...
- springboot+websocket示例
1.新建maven工程 工程结构如下: 完整的pom.xml如下: <?xml version="1.0" encoding="UTF-8"?> & ...
- SQL语句之奇形怪状的冷门函数
lag() over() ) OVER(ORDER BY C.column) FROM Table C; 第一条记录已经无法再取前一条记录,所以LAG()函数返回空. SQL为意思如下. LAG(C. ...
- SQL之GROUP BY 语句
合计函数 (比如 SUM) 常常需要添加 GROUP BY 语句. GROUP BY 语句 GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组. SQL GROUP BY 语法 ...