模型原型:服务器的配置和运行状态信息。

设计要求: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数据展示程序(第一版)的更多相关文章

  1. 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 ...

  2. Spring MVC返回json数据给Android端

    原先做Android项目时,服务端接口一直是别人写的,自己拿来调用一下,但下个项目,接口也要自己搞定了,我想用Spring MVC框架来提供接口,这两天便抽空浅学了一下该框架以及该框架如何返回json ...

  3. Spring MVC生成JSON数据

    以下示例演示如何使用Spring Web MVC框架生成JSON数据格式.首先使用Eclipse IDE,并按照以下步骤使用Spring Web Framework开发基于动态表单的Web应用程序: ...

  4. 调取jSon数据--展示

    下面代码是将页面中的展示部分 function searchProductlistByfilterCondition(index, type, sort, filterWord) { //cite_h ...

  5. ArcGIS Server 10.2 实战(一)Asp.net MVC与JSON数据妙用实现动态生成要素图层

    今年7月刚刚发布的ArcGIS 10.2为GIS的web开发带来了一个很实在的功能,JSON转要素.以往GIS图层外部数据(如文本数据,数据库数据)动态地写入地图服务中的图层是一件不可想象的事情,如今 ...

  6. JSON数据展示神器:react-json-view(常用于后台网站)

    一.react-json-view - npm 官方定义: RJV is a React component for displaying and editing javascript arrays ...

  7. Spring MVC之JSON数据交互和RESTful的支持

    1.JSON概述 1.1 什么是JSON JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式.它是基于JavaScript的一个子集,使用了C.C ...

  8. ES6_Demo,模拟后台json数据展示

    最近在学习ES6,下面,模拟后台传过来json数据,并在页面展示的一个小Demo. 页面简单的不可描述,只有一个button按钮 <button>点击获取json数据</button ...

  9. spring mvc 返回json数据的四种方式

    一.返回ModelAndView,其中包含map集 /* * 返回ModelAndView类型的结果 * 检查用户名的合法性,如果用户已经存在,返回false,否则返回true(返回json数据,格式 ...

随机推荐

  1. 不立flag了……

    当天刚说再也不想下这游戏了,后来和女友聊了会天视了会屏又动摇了..后悔和她那么计较这些小事,可能玩游戏时生气时就想不起来那么多事了吧..于是游戏过两天就又下回来了.. 这两天培训课程也是很快的感觉,昨 ...

  2. IOS 单击手势和cell点击冲突

    环境: view上添加tableView,给view添加单击手势,点击cell却走的是手势方法. 解决: UITapGestureRecognizer *tap=[[UITapGestureRecog ...

  3. 2019.01.23 hdu1964 Pipes(轮廓线dp)

    传送门 题意简述:给一个没有障碍的网格图,任意两个格子连通需要花费一定代价,现在求一条覆盖所有格子的哈密顿回路的总权值的最小值. 思路: 跟这道题一毛一样,除了把求和变成求最小值以外. 代码: #in ...

  4. Firefox,chrome,IE上传图片预览

    首先判断IE或是Firefox,chrome.本文只测试了IE8中和Firefox,chrome是不一样的. 判断是否IE: if(-[1,]){//判断浏览器不是IE    //alert((-[1 ...

  5. ES6通过使用babel兼容到ie9

    1.打开这个地址: https://unpkg.com/babel-standalone@6/babel.min.js 新建babel.min.js,把代码复制进去,然后在jq项目里引用. 2.在下面 ...

  6. D. Three Pieces(dp,array用法,棋盘模型)

    https://codeforces.com/contest/1065/problem/D 题意 给你一个方阵,里面的数字从1~nn,你需要从标号为1的格子依次走到标号为nn,在每一个格子你有两个决策 ...

  7. hdu6365 2018 Multi-University Training Contest 6 1004 Shoot Game

    http://acm.hdu.edu.cn/showproblem.php?pid=6365 细节处理 unique返回的是最后一位的后一位,因此从1开始的数组要减去(p+1) 结构体可以用unqiu ...

  8. CentOS7 安装可视化脚本安装包Webmin

    一.简介 Webmin是一个基于Web的Linux系统管理界面.你就可以通过图形化的方式设置用户账号.Apache.DNS.文件共享等服务. 二.安装 1.下载安装包到本地Windows系统 http ...

  9. 第08章:MongoDB-CRUD操作--文档--删除

    ①语法 remove()  [2.6以后方法过时] deleteOne() [2.6以后官方推荐] deleteMany() [2.6以后官方推荐] db.collection.remove( < ...

  10. 轻松建立Silverlight开发环境

    创建Silverlight 4开发环境,微软提供最简单的方法是使用Web Platform Installer,进行“一键安装”, 下载安装后,Web Platform Installer会自动检测哪 ...