视图 (View)
代表用户交互界面,对于 Web 应用来说,可以概括为 HTML 界面,但有可能为 XHTML、XML 和 Applet。
模型(Model)
表示用户对其数据的操作的一个封转。可以分为视图模型(view model)和领域模型(domain models),视图模型就是在视图与控制器之间传输数据的一个封转,而领域模型就是业务逻辑,后台数据模型等的一个集合。是我们学的 3 层中的 BLL,DAL,Models 的集合
控制器(Controller)
控制器可以理解为从用户接收请求,将模型与视图匹配在一起,共同完成用户的请求。
当在浏览器中输入一个 URL,进入了 Route 系统,路由系统得到 URL 各个片段的值,并交给 MVC 处理,MVC 依据 URL 的信息知道请求的 Action,接着就对模型进行一系列的处理,然后呈现视图。
MVC 对控制器与 View 有一定的限制,但对模型没有任何的限制。
控制器必须实现 IController 接口或者继承 Controller 类,控制器类中的公有方法称之为 Action Method。
在 MVC 项目中有 2 种习惯
a、建议你如何组织项目中的一些文件,比如 js 文件放在 Scripts 文件夹下,像这种习惯,你完全可以不遵循,这些文件夹和文件删除并不影响 MVC 框架本身。
b、另外一种,有个专门的术语:"Convention over configuration", 意思就是说如果你遵循了这个习惯就不需要进行额外的配置或编码(特别是控制器与视图)。这种习惯就尽量遵循,如果违反,在 MVC 中就需要做许多的事情。
主要有 3 个方面:
a、控制器命名习惯:控制器类必须以 Controller 结尾,但引用这个控制器的时候可以省略掉 Controller,如果想改变这种行为,需要自己实现 IControllerFactory 接口,默认是通过 DefaultControllerFactory 来执行这个控制器的查找的。
b、视图命名习惯:视图或者分部视图应该放在 / Views/Controllername 文件夹下面,比如一个控制器为 Demo 那么这个控制器的所有视图应该放在 / Views/Demo / 下面,默认情况下,每一个 Action Method 对应一个视图,尽
量让视图名字与 Action 名字一样,这样在 Action 中就可以直接 return View(); 而放在 Shared 文件夹下面的视图所有的控制器都可以使用
c、布局命名习惯:布局文件都以下划线开头,并放置在 shared 文件夹下面,在 MVC 3 中默认每个视图都会用到_layout.cshtml 布局,可以在_viewstart.cshtml 看到这个设置
优点:
A、具有多个视图对应一个模型的能力。
B、由于一个应用被分离为三层,因此有时改变其中的一层就能满足应用的改变。一个应用的业务流程或者业务规则的改变只需改动 MVC 的模型层。
C、它还有利于软件工程化管理。由于不同的层各司其职,每一层不同的应用具有某些相同的特征,有利于通过工程化、工具化产生管理程序代码。
缺点:
A、增加了系统结构和实现的复杂性。
B、视图与控制器间的过于紧密的连接。
C、视图对模型数据的低效率访问。
创建第一个 MVC 应用程序之前,首先说明一下我的电脑使用配置环境:VS2013 与 SQLSever2012。
1、首先打开 VS2013, 新建一个 MVC4 项目。
2、点击确定后会弹出如下图界面。
3、点击确定后会自动生成如下默认项目结构。
4、在 Controller 文件夹上右键添加一个控制器。
5、点击添加按钮后,生成 HomeController 类,默认生成 Index() 方法如下:
6、现在 Controller 控制器已经创建好了,下面来创建一个 View 视图了,添加添加视图两种方式:方式一:在控制器里的 Index() 方法里右键添加视图,方式二:在 View 文件夹上右键添加一个与 HomeController 控制器名称相同的文件夹如:Home 文件夹,在该文件夹上右键添加一个与 Index() 方法同名的视图。这里选择选择方式一创建方法如下所示:
7、最终添加视图后的界面,开始运行浏览查看结果。
到这里我们的第一个 MVC 程序 Hello World 就完成了,是不是感觉很简单。那么接下来就来学习写一个关于 Asp.Net MVC 的增删改查的简单测试案例吧。已经学习过 Asp.Net 的同学可以先思考一下如何用 MVC 实现一个增删改查的的功能。没有学习过的同学可以思考下逻辑三层与 MVC 中 Model 的联系,下面这个简单测试案例将让你对 MVC 概念的理解的更明白些。
测试案例增删改查效果图如下:
1、首先准备数据库数据。
- use master
- go
- create database Demo
- go
- use Demo
- go
- create table Product
- (
- ID int primary key identity(1,1),
- Name nvarchar(20),
- Price decimal
- )
- go
- insert into Product values('电脑垫',22),('鼠标',55),('键盘',22),('网线',32),('U盘',100),('咖啡',55),('书籍',99),('牛奶',5)
- go
2、打开 VS2013 创建一个名为 MvcFristDemo 的 MVC4 项目,创建步骤与上面一致,这里步骤不再详细介绍,最终项目创建完成截图如下。
这里需要说明一下添加视图的步骤与上面 Hello World 示例有所区别:因为要用到 Model 模型,所以在添加视图的时候需要选中如下图中的创建强类型视图 模型选择 Product 模型。
3、步骤一:ProductController 控制器代码如下。
- 1 using MvcFirstDemo.Models;
- 2 using System;
- 3 using System.Collections.Generic;
- 4 using System.Linq;
- 5 using System.Web;
- 6 using System.Web.Mvc;
- 7
- 8 namespace MvcFirstDemo.Controllers
- 9 {
- 10 public class ProductController : Controller
- 11 {
- 12 public ActionResult List()
- 13 {
- 14 List result = new ProductBll().Select();
- 15 return View(result);
- 16 }
- 17
- 18
- 19 public ActionResult Add()
- 20 {
- 21 return View();
- 22 }
- 23 [HttpPost]
- 24 public ActionResult Add(Product p)
- 25 {
- 26 bool result = new ProductBll().Insert(p);
- 27 return RedirectToAction("List");
- 28 }
- 29
- 30 public ViewResult Update(int id)
- 31 {
- 32 Product p = new ProductBll().GetProductById(id);
- 33 return View(p);
- 34 }
- 35 [HttpPost]
- 36 public ActionResult Update(Product p)
- 37 {
- 38 bool result = new ProductBll().Update(p);
- 39 return RedirectToAction("List");
- 40 }
- 41
- 42 public ActionResult Delete(int id)
- 43 {
- 44 bool result = new ProductBll().Delete(id);
- 45 return RedirectToAction("List");
- 46 }
- 47 }
- 48 }
4、步骤二:Model 文件夹中的三个类代码如下。
Product.cs 代码如下:
- 1 using System;
- 2 using System.Collections.Generic;
- 3 using System.Linq;
- 4 using System.Web;
- 5 6 namespace MvcFirstDemo.Models 7 {
- 8 public class Product 9 {
- 10 public int ID {
- get;
- set;
- }
- 11 public string Name {
- get;
- set;
- }
- 12 public decimal Price {
- get;
- set;
- }
- 13
- }
- 14
- }
ProductBll.cs 代码如下:
- 1 using System;
- 2 using System.Collections.Generic;
- 3 using System.Linq;
- 4 using System.Web;
- 5 6 namespace MvcFirstDemo.Models 7 {
- 8 public class ProductBll 9 {
- 10 ProductDal dal = new ProductDal();
- 11 public List Select() 12 {
- 13
- return dal.Select();
- 14
- }
- 15 public Product GetProductById(int id) 16 {
- 17
- return dal.GetProductById(id);
- 18
- }
- 19 public bool Update(Product p) 20 {
- 21
- return dal.Update(p);
- 22
- }
- 23 24 public bool Insert(Product p) 25 {
- 26
- return dal.Insert(p);
- 27
- }
- 28 29 public bool Delete(int id) 30 {
- 31
- return dal.Delete(id);
- 32
- }
- 35
- }
- 36
- }
ProductDal.cs 代码如下:
- 1 using System;
- 2 using System.Collections.Generic;
- 3 using System.Data.SqlClient;
- 4 using System.Linq;
- 5 using System.Web;
- 6
- 7 namespace MvcFirstDemo.Models
- 8 {
- 9 public class ProductDal
- 10 {
- 11 string connStr = @"server=PC-201511211346\MSSQLSERVER2;database=Demo;uid=sa;pwd=123456;";
- 12 public List Select()
- 13 {
- 14 using (SqlConnection conn = new SqlConnection(connStr))
- 15 {
- 16 conn.Open();
- 17 string SQL = "select * from Product";
- 18 SqlCommand cmd = new SqlCommand(SQL, conn);
- 19 using (SqlDataReader sdr = cmd.ExecuteReader())
- 20 {
- 21 List list = new List();
- 22 Product obj = null;
- 23 while (sdr.Read())
- 24 {
- 25 obj = new Product
- 26 {
- 27 ID = Convert.ToInt32(sdr["ID"]),
- 28 Name = sdr["Name"].ToString(),
- 29 Price = Convert.ToDecimal(sdr["Price"])
- 30 };
- 31 list.Add(obj);
- 32 }
- 33 return list;
- 34 }
- 35 }
- 36 }
- 37
- 38 public bool Insert(Product p)
- 39 {
- 40 using (SqlConnection conn = new SqlConnection(connStr))
- 41 {
- 42 conn.Open();
- 43 string SQL = "insert into Product values(@Name,@Price)";
- 44 SqlCommand cmd = new SqlCommand(SQL, conn);
- 45 cmd.Parameters.AddWithValue("Name", p.Name);
- 46 cmd.Parameters.AddWithValue("Price", p.Price);
- 47 return cmd.ExecuteNonQuery() > 0 ? true : false;
- 48 }
- 49 }
- 50
- 51 public bool Update(Product p)
- 52 {
- 53 using (SqlConnection conn = new SqlConnection(connStr))
- 54 {
- 55 conn.Open();
- 56 string SQL = "update Product set Name=@Name,Price=@Price where ID=@ID";
- 57 SqlCommand cmd = new SqlCommand(SQL, conn);
- 58 cmd.Parameters.AddWithValue("@ID", p.ID);
- 59 cmd.Parameters.AddWithValue("@Name", p.Name);
- 60 cmd.Parameters.AddWithValue("@Price", p.Price);
- 61
- 62 return cmd.ExecuteNonQuery() > 0 ? true : false;
- 63 }
- 64 }
- 65
- 66 public bool Delete(int id)
- 67 {
- 68 using (SqlConnection conn = new SqlConnection(connStr))
- 69 {
- 70 conn.Open();
- 71 string SQL = "delete from Product where ID=@ID";
- 72 SqlCommand cmd = new SqlCommand(SQL, conn);
- 73 cmd.Parameters.AddWithValue("@ID", id);
- 74 return cmd.ExecuteNonQuery() > 0 ? true : false;
- 75 }
- 76 }
- 77
- 78 internal Product GetProductById(int id)
- 79 {
- 80 using (SqlConnection conn = new SqlConnection(connStr))
- 81 {
- 82 conn.Open();
- 83 string SQL = "select * from Product where ID=@ID";
- 84 SqlCommand cmd = new SqlCommand(SQL, conn);
- 85 cmd.Parameters.AddWithValue("@ID", id);
- 86 using (SqlDataReader sdr = cmd.ExecuteReader())
- 87 {
- 88 Product obj = null;
- 89 while (sdr.Read())
- 90 {
- 91 obj = new Product
- 92 {
- 93 ID = Convert.ToInt32(sdr["ID"]),
- 94 Name = sdr["Name"].ToString(),
- 95 Price = Convert.ToDecimal(sdr["Price"])
- 96 };
- 97 }
- 98 return obj;
- 99 }
- 100 }
- 101 }
- 102 }
- 103 }
5、步骤三:View 文件夹中三个视图代码如下。
这里需要说明一下的是对 List.aspx 页面中图一中默认生成代码改成图二中代码,修改成红色部分代码:<%@ Page Language="C#"Inherits="System.Web.Mvc.ViewPage<List<MvcFirstDemo.Models.Product>>" %>
为什么要这样修改呢?因为我们在 ProductDal.cs 类中的 Select() 方法返回的是 list
List.aspx 页面代码如下:
- 1 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<List<MvcFirstDemo.Models.Product>>" %>
- 2
- 3 <!DOCTYPE html>
- 4
- 5 <html>
- 6 <head runat="server">
- 7 <meta name="viewport" content="width=device-width" />
- 8 <title>List</title>
- 9 </head>
- 10 <body>
- 11 <div>
- 12 <table cellspacing="1" border="1">
- 13 <tr>
- 14 <td>产品ID</td>
- 15 <td>产品名称</td>
- 16 <td>产品价格</td>
- 17 <td>操作 <a href="Product/Add">增加</a></td>
- 18 </tr>
- 19 <%
- 20 foreach (var item in Model)
- 21 {
- 22 %>
- 23 <tr>
- 24 <td><%=item.ID %></td>
- 25 <td><%=item.Name %></td>
- 26 <td><%=item.Price %></td>
- 27 <td>
- 28 <a href="/Product/Update?id=<%=item.ID %>">修改</a>
- 29 <a href="/Product/Delete?id=<%=item.ID %>">删除</a>
- 30 </td>
- 31 </tr>
- 32 <%
- 33 }
- 34 %>
- 35 </table>
- 36 </div>
- 37 </body>
- 38 </html>
Add.aspx 页面代码如下:
- 1 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcFirstDemo.Models.Product>" %>
- 2
- 3 <!DOCTYPE html>
- 4
- 5 <html>
- 6 <head runat="server">
- 7 <meta name="viewport" content="width=device-width" />
- 8 <title>Add</title>
- 9 </head>
- 10 <body>
- 11 <div>
- 12 <form action="/Product/Add" method="post">
- 13 <input type="text" name="Name" value=" " />
- 14 <input type="text" name="Price" value=" " />
- 15 <input type="submit" name="submit" value="增加" />
- 16 </form>
- 17 </div>
- 18 </body>
- 19 </html>
Update.aspx 页面代码如下:
- 1 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcFirstDemo.Models.Product>" %>
- 2
- 3 <!DOCTYPE html>
- 4
- 5 <html>
- 6 <head runat="server">
- 7 <meta name="viewport" content="width=device-width" />
- 8 <title>Update</title>
- 9 </head>
- 10 <body>
- 11 <div>
- 12 <form action="/Product/Update" method="post">
- 13 <input type="hidden" name="ID" value="<%=Model.ID%>" />
- 14 <input type="text" name="Name" value="<%=Model.Name %>" />
- 15 <input type="text" name="Price" value="<%=Model.Price %>" />
- 16 <input type="submit" name="submit" value="修改" />
- 17 </form>
- 18 </div>
- 19 </body>
- 20 </html>
解决办法:把图二中的参数名 dd 改成与图一中传递的参数名 id 一样的名字即可解决为 null 问题获得数据。
解决办法:在如下图中方法重载代码处,其中一个方法添加一个特性如 [HttpPost]、[HttpPut]、[HttpPatch],即可解决此问题, 至于添加哪个特性需要依据你发起请求的方法而决定。
解决办法:此问题的解决办法在上面步骤三中已做解释说明,这里不再重复解释。
解决办法:把下图中的传递表单数据的参数名字改成与 Product 模型类里的字段名一样即可获得表单传递过来的数据。
解决办法:查看页面代码发现浏览器请求的页面路径并没有错误,但是运行又确实报错,找不到请求 URL 指定路径的页面,这该怎么办呢?我们冷静分析一下,这里其实牵涉到了一个知识点,就是你对 MVC 原理的理解,在前面 1.2、Asp.Net MVC 的原理节中已经讲到 MVC 的原理,所以这里我们只需要做如下图所示修改即可解决此问题。
下载地址:
总结:在本文章中,主要是对理解 ASP.NET MVC 的相关概念做了个简单介绍,以及通过一个 MVC 增删改查简单测试案例帮助初学者加深对 MVC 模式的理解,最后还总结了初学者几个常见的错误,让初学者少走点弯路。
来源: http://www.cnblogs.com/SeeYouBug/p/6401737.html