mvc_1_ex_stu_manage
Mvc第一遍结束综合练习:带权限的学生管理系统
程序的设计应该根据功能来进行。先来设想一下本练习的程序功能:学生信息管理、登录用户区分权限、出错应该给出提示。
由此可以设想,完成以后的程序是下图的样子:
主界面:
点击右上角的“登录”,出现登录界面:
任何错误,都在错误页面处理:
以上是整个程序的界面部分。整个练习不做任何美工方面的考虑。
基于这样的程序功能,接下来进行程序设计。
数据库设计:
库中至少应该包含学生信息表和用户表。做最简单的设计如下:
学生表:
用户表:
以此为基础,完成数据库
用户表内容:
学生表内容:
根据前面的功能界面,设计视图、控制器、业务逻辑层、模型层如下:
注意:控制器、业务逻辑和模型之间,没有表中必然的对应关系。这么列表就是为了看着方便。
有了这样的分工概念,接下来创建对应的文件夹和文件
然后可以按照你喜欢的顺序完成这九个部分(views里面的三个视图忘记展开了)。
这里采用表中从右到左的顺序作为项目的完成顺序。
Student.cs:
对照数据库,考虑到学生基本信息,可以完成类的属性编写。结合操作(增删改查),确定完成四项基本功能。补上构造函数,文件内容如下:
- class Student
- {
- string id,xm, nl, zy,sql;//sql是某条记录准备执行的操作语句
- public Student(string input_id)//构造函数1,只初始化编号,显然准备删除自己
- {
- id = input_id;
- }
- public Student(string input_xm,string input_nl,string input_zy)//构造函数2,没有编号,看样子要把自己插入表中
- {
- xm=input_xm;
- nl = input_nl;
- zy = input_zy;
- }
- public Student(string input_id,string input_xm, string input_nl, string input_zy)//构造函数3,啥都有,用于更新
- {
- id = input_id;
- xm = input_xm;
- nl = input_nl;
- zy = input_zy;
- }
- public void insert_it()//插入方法
- {
- sql = "insert into xs(xm,nl,zy) values('"+xm+"',"+nl+",'"+zy+"')";
- Hc_db.do_nonquery(sql);
- }
- public void modify_it()//修改方法
- {
- sql = "update xs set xm='"+xm+"',nl="+nl+",zy='"+zy+"' where id="+id;
- Hc_db.do_nonquery(sql);
- }
- public void delete_it()//删除方法
- {
- sql = "delete from xs where id=" + id;
- Hc_db.do_nonquery(sql);
- }
- public DataTable select_it()
- {
- sql= "select * from xs where id=" + id;
- return Hc_db.get_datatable(sql);
- }
- }
接下来,开始写学生管理的业务逻辑。由于“查”分为按学号查和全查,所以它一共有五个操作。可以看到,在模型的支持下,它变得很简单。Bll.cs代码如下:
- class Bll
- {
- public static DataTable get_All()
- {
- DataTable dt1;
- dt1 = Hc_db.get_datatable("select id as 学号,xm as 姓名,nl as 年龄,zy as 专业 from xs");
- return dt1;
- }
- public static void delet_Student(string id)
- {
- Student s1 = new Student(id);
- s1.delete_it();
- }
- public static void add_Student(string xm,string nl,string zy)
- {
- Student s1 = new Student(xm,nl,zy);
- s1.insert_it();
- }
- public static void modi_Student(string id, string xm, string nl, string zy)
- {
- Student s1 = new Student(id,xm,nl,zy);
- s1.modify_it();
- }
- public static DataTable get_Student(string id)
- {
- Student s1 = new Student(id);
- return s1.select_it();
- }
- }
练习里的用户逻辑很简单,只需要根据用户名密码判断是否能登录,登录之后给出具体权限就好。User_Manage.cs代码如下:
- public class User_Manage
- {
- public static void user_Login(string u,string pass,out bool result,out int power)
- {
- string sql = $"select * from user1 where user_name='{u}' and password='{pass}'";
- DataTable dt1;
- dt1 = Hc_db.get_datatable(sql);
- if(dt1.Rows.Count>0)
- {
- result = true;
- power = int.Parse(dt1.Rows[0][3].ToString());
- }
- else
- {
- result = false;
- power = 0;
- }
- }
- }
可以看到,缺乏模型的支持,业务逻辑写起来稍微显得复杂了一点。
后方稳固,老板上场。Home控制器主要根据送入的参数来调动手头资源,再把需要呈现的东西送给视图。Index方法,在送入的参数方面,要考虑的问题主要有:1、用户操作增删改查时,送入哪些参数,根据参数决定操作。这一部分考虑由Action的参数来表达;2、如何确定用户的权限,这一部分考虑用session来表达;3、在第一次访问这个页面(参数和session都为空)的时候,程序应该如何处理。无论如何,它都应该带回一个在数据库中查询的结果。基于这些考虑,HomeController.cs的Index方法代码如下:
- public ActionResult Index(string id="0",string xm="0", string nl = "0", string zy = "0")
- {
- string s;
- if(Session["u"]==null)
- {
- Session["u"] = "guest";
- Session["p"] = 0;
- }
- if(id!="0")
- {
- s = Request["s"];
- if (s == "添加")
- {
- if (int.Parse(Session["p"].ToString()) < 40)
- {
- Response.Redirect("/wrong/index?msg=Power Low!");
- }
- else
- {
- Bll.add_Student(xm, nl, zy);
- }
- }
- else if (s == "删除")
- {
- if (int.Parse(Session["p"].ToString()) < 90)
- {
- Response.Redirect("/wrong/index?msg=Power Low!");
- }
- else
- {
- Bll.delet_Student(id);
- }
- }
- else if (s == "修改")
- {
- if (int.Parse(Session["p"].ToString()) < 40)
- {
- Response.Redirect("/wrong/index?msg=Power Low!");
- }
- else
- {
- Bll.modi_Student(id, xm, nl, zy);
- }
- }
- else
- {
- ViewData["mydata"] = Bll.get_Student(id);
- }
- }
- if (ViewData["mydata"] == null)
- {
- ViewData["mydata"] = Bll.get_All();
- }
- return View();
- }
相比之下,Login方法相对简单。它只需要考虑1、请求这个页面时,呈现什么;2、接受到用户提交的用户名密码时,做些什么;3、登录成功和失败,分别返回什么。代码如下:
- public ActionResult Login(string un = "0",string pw="0")
- {
- bool ok;
- int qx;
- if (un == "0")
- {
- return View();
- }
- else
- {
- User_Manage.user_Login(un, pw,out ok,out qx);
- if(ok)
- {
- Session["u"] = un;
- Session["p"] = qx;
- Response.Redirect("/home/index");
- }
- else
- {
- Response.Redirect("/wrong/index?msg=login wrong");
- }
- }
- return View();
- }
出错控制器很简单,给个错误页面就好。如果想要呈现不同的错误信息,最简单的方法是在重定向到它的时候,把错误信息传过去。这里通过查询字符串传递进来,viewdata传递给视图,代码如下:
- public class WrongController : Controller
- {
- // GET: Wrong
- public ActionResult Index(string msg="")
- {
- if(msg!="")
- {
- ViewData["mydata"] = msg;
- }
- return View();
- }
- }
调用方式就可以是这个样子:
Response.Redirect("/wrong/index?msg=xxx");
有了控制器送过来的内容,接下来界面就很好做了。按照前面程序效果的设想,Index.cshtml主要分为三部分。最上面显示用户信息,中间显示学生信息,下面进行操作。其中用户信息主要由session控制,学生信息主要由dataview呈现,操作部分主要由表单完成。代码如下:
- @using System.Data;
- @{
- Layout = null;
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Index</title>
- </head>
- <body>
- <div>
- <div style="text-align:right;">
- 用户:@Session["u"].ToString()
- 权限:@Session["p"].ToString()
- @{
- if(Session["p"].ToString()=="")
- {
- <a href="/home/login">登录</a>
- }
- }
- </div>
- <hr />
- <div>
- @if (ViewData["mydata"] != null)
- {
- <table style="width: 100%; border-color:black; padding:0px; border-collapse:collapse;" border=''>
- @{
- DataTable a = (DataTable)ViewData["mydata"];
- <tr>
- @for (int j = ; j < a.Columns.Count; j++)
- {
- <td>@(a.Columns[j].ColumnName)</td>
- }
- </tr>
- for (int i = ; i < a.Rows.Count; i++)
- {
- <tr>
- @for (int j = ; j < a.Columns.Count; j++)
- {
- <td>@(a.Rows[i][j].ToString())</td>
- }
- </tr>
- }
- }
- </table>
- }
- </div>
- <hr />
- <div>
- <form>
- 学号:<input type="text" name="id" />
- 姓名:<input type="text" name="xm" />
- 年龄:<input type="text" name="nl" />
- 专业:<input type="text" name="zy" /><br />
- <input type="submit" name="s" value="添加" />
- <input type="submit" name="s" value="删除" />
- <input type="submit" name="s" value="修改" />
- <input type="submit" name="s" value="查询" />
- </form>
- </div>
- </div>
- </body>
- </html>
登录页面Login.cshtml很简单,一个表单即可。代码如下:
- @{
- Layout = null;
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Login</title>
- </head>
- <body>
- <div>
- <form>
- 用户名:<input type="text" name="un" /><br />
- 密码:<input type="text" name="pw" /><br />
- <input type="submit" value="登录" />
- </form>
- </div>
- </body>
- </html>
错误页面Wrong.cshtml呈现即可,代码如下:
- @{
- Layout = null;
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>Index</title>
- </head>
- <body>
- <div>
- 操作失败!<br />
- @{
- if(ViewData["mydata"]!=null)
- {
- <p>@ViewData["mydata"].ToString()</p>
- }
- }
- </div>
- </body>
- </html>
调试。
看懂了,就把它忘掉,然后自己写一遍。对照着写和抄代码,你学不到任何东西。
至此,整个练习全部完成。正所谓“麻雀虽小五脏俱全”。我们已经能够使用mvc方式完成一个网站的编写,并且体会到这种“松耦合”方式的好处,即:每个小部分都很简单,想要改进(比如界面),其他部分基本都不用动。
回顾整个项目,看看有什么感觉。比如:
Home控制器里,Index方法做的事情是不是还是太复杂了?不像一个老板。而厨房,太清闲了吧。权限判断这样的事情,是不是应该由业务逻辑层来完成?怎么改?自己想想,试试吧。
还有,各个部分之间的跳转、数据的传递,是不是还是感觉怪怪的?写起来很麻烦?在第二遍的学习中,这些问题会有所改善。
mvc_1_ex_stu_manage的更多相关文章
随机推荐
- MySQL使用alter修改表的结构
SQL语句 DLL 数据定义语言 create,drop DML 数据操纵语言 insert,delete,select,upda ...
- Java错误体系
1.Java所有的异常错误都继承与Throwable类,只有继承了Throwable类,才能在异常传递体系中进行. 2.Throwable下有两个重要的子类,Error和Exception Error ...
- 文件转换神器pandoc
pandoc :可以在各种文件之间进行相互转化.比如从md文件转为pdf,docx转为tex文件,html文件和txt文件相互转化,等等. 在终端启用命令行执行命令. 我最近要完成的任务是把有很多个 ...
- Springboot JackSon
1. SpringBoot JSON工具包默认是Jackson,只需要引入spring-boot-starter-web依赖包,自动引入相应依赖包: <dependency> <gr ...
- 【Linux】bat文件如何执行
绝对路径,"/home/myDir/xxx.bat" OR 所在的目录,:"./xxx.bat".
- Jmeter函数助手—自带方法
1.${__time()}---->当前时间,一串数字格式 2.${__time(yyyy-MM-dd)}----->当前日期,年-月-日格式 3.${__time(yyyy-MM-dd ...
- 4.28(TG模拟赛)总结
1.挖地雷 题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N≤20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之后,某人可以从任 ...
- 常见的概率分布类型(二)(Probability Distribution II)
以下是几种常见的离散型概率分布和连续型概率分布类型: 伯努利分布(Bernoulli Distribution):常称为0-1分布,即它的随机变量只取值0或者1. 伯努利试验是单次随机试验,只有&qu ...
- 在eclipse中新建java问题报错:The type XXX cannot be resolved. It is indirectly referenced from required .class files
在Eclipse中遇到The type XXX cannot be resolved. It is indirectly referenced from required .class files错误 ...
- 三天精通Vue--ES6的常用语法
详细学习请参考 阮一峰的ECMAScript 6 入门 let和const的使⽤ es5中使用var来声明全局变量 es5中我们学习了使用var来声明变量,但是使用var声明变量,会存在变量提升的问 ...