ASP.NET MVC
oo1 Mvc准备工作
课程安排:ORM->AspNet MVC
开发环境:VS2012/VS2013
SqlServer2008/2005
主讲Asp.Net Mvc4 Razor
官网:http://www.asp.net/mvc/mvc4
002 自动属性
知识储备:
自动属性
隐式类型 var
匿名类
对象初始化与集合初始化
扩展方法
Lambda表达式
Product(Id,Name,Description,Price,Category)
003 var关键字
var num=10;
var根据右边的值推断类型
num=10m;//报错,不能修改类型
只能修饰本地变量/临时变量,不能修饰字段
004 匿名类
var p=new {Age=10,Name="Rocky"};//new一个匿名类得对象
p.Age=20;//报错,匿名类得属性是只读的
005 集合和对象初始化器
Product p = new Product() { Id = 1, Name = "Rocky", Description = "一毛钱", Price = 10, CategoryId = 1 };//可以去掉“()”
List<string> list = new List<string>() { "梅西", "卡卡", "郑大世" };//可以去掉"()"
006 扩展方法
给拥有的但不能修改的类动态添加一个扩展方法
static class MyExtendMethod
{
public static string SayHello(this object obj, string str) //给类object添加扩展方法SayHello,类和方法都是static
{
return str;
}
}
007 lambda表达式
从委托说起,委托用于存储方法
delegate int MyDel(int x);//委托是用来存储方法的
//lambda表达式
//MyDel del = new MyDel(AddOne);//用方法AddOne初始委托
//MyDel del = delegate(int x) { return x + 1; };//用匿名函数初始化委托
//MyDel del = (int x) => { return x + 1; };//goes to
//MyDel del = (x) => { return x + 1; };
//MyDel del = x => { return x + 1; };
MyDel del = x => x + 1;
Console.WriteLine(del(1));
public static int AddOne(int x)
{
return x + 1;
}
008 ORM概念(Object Relational Mapping映射)
广义上,ORM指定的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换,
是一种解决面向对象语言和关系型数据库不匹配的技术。
狭义上,ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据访问接口。
理想情况下,基于这样一个面向对象的接口,持久化一个OO对象应该不需要了解任何关系型数据库存储数据的实现细节。
即应用程序与数据库的映射关系,帮助完成对象的自动生成,sql语句的查询等
009 初识EF
实体框架EF(Entity Framework)
ORM与EF的关系:EF是基于ORM思想完成的技术框架(iBATIS.NET,Nhibernate)
EF与ADO.NET关系:实体框架Entity Framework 是ADO.NET中的一组支持开发面向数据的软件应用程序的技术。是微软的一个ORM框架.
新建控制台程序EFDBDemo--添加ADO.NET实体数据模型EFDB.edmx--从数据库生成--新建连接--是,在连接字符串中包含铭感数据EFDBEntities--选择6.0框架--模型中包含哪些表--完成
ENtityFramework和ENtityFramework.SqlServer包含通过EF操作数据库的所有类
EFDB.tt中Product是实体类
EFDB.Context.cs的EFDBEntities是数据上下文类,继承DbContext,凡是继承DbContext都是操作数据库的数据上下文类
base("name=EFDBEntities")中的字符串就是给父类把连接字符串的名字传递过来
IEnumerable<TEntity>初始化这个类
010 EF添加
//插入
//实例化一个数据上下文对象(所有对数据库的操作都是通过数据上下文实现的)
EFDBEntities entity = new EFDBEntities();
//向数据上下文对象添加数据实体
T_Product p = new T_Product() { Name = "RuPeng", Description = "我的老师", Price = 100m, Category = "教育" };
entity.T_Product.Add(p);
//告诉数据上下文对象我要对哪个实体对象执行哪种操作
entity.Entry(p).State = EntityState.Added;//对p对象执行插入操作(using System.Data.Entity;)
//把我们对数据库的操作执行
entity.SaveChanges();//保存数据的变化(生成sql语句的过程)
打开数据库监控工具,SQL Server中的性能工具--SQL Server Profiler--新建跟踪--
011 EF删改查
//修改
EFDBEntities entity = new EFDBEntities();
T_Product p = new T_Product();
p.Id = 1;
p.Name = "yang";
p.Description = ".net";
p.Price = 1000m;
p.Category = "IT";
entity.Entry(p).State = EntityState.Modified;
entity.SaveChanges();
//删除
EFDBEntities entity = new EFDBEntities();
T_Product p = new T_Product();
p.Id = 1;
entity.Entry(p).State = EntityState.Deleted;
entity.SaveChanges();
//查询
EFDBEntities entity = new EFDBEntities();
var list = entity.T_Product;
foreach (var item in list)
{
Console.WriteLine(item.Name);
}
012 EFmodeFirst
DBFirst数据库先行(从数据库到应用程序的映射)
ModelFirst实体先行(从应用程序到数据库的映射,把实体保存到数据库)
ModelFirst例子:
新建ModelFirst控制台项目--添加ADO.NET实体数据模型--空模型--添加实体--添加标量变量--根据模型生成数据库--执行sql语句--完成
013 ModelFirst补充
如果每次跟新数据库都重新创建数据库的表,很可能数据库中的特殊数据特殊键会丢失,所以工作中少用ModelFirst
而是从数据库更新模型(这里如果数据表的名字没有发生变化,不会允许选择数据表)
创建实体之间的关系:新增关联--根据模型生成数据库
014 MF插入
数据表Student与Teacher之间的关系通过导航属性进行关联
//插入
EFDBModelContainer EFDB = new EFDBModelContainer();
Student s = new Student() { Name = "杨过", Address = "苏州市", Gender = true, Score = 100 };
Teacher t = new Teacher() { Name = "以为军" };
s.Teacher = t;//改学生关联的老师是t
EFDB.Entry(s).State = EntityState.Added;//让数据上下文对哪个实体执行某种操作
EFDB.Entry(t).State = EntityState.Added;
EFDB.SaveChanges();//执行对数据库的操作
015 MF修改删除
//修改
EFDBModelContainer EFDB = new EFDBModelContainer();
Student s = new Student();
s.Id = 1;
s.Name = "痒痒";
s.Birthday = DateTime.Now;
Teacher t = new Teacher();
t.Id = 1;
t.Name = "Rocky";
EFDB.Entry(s).State = EntityState.Modified;
EFDB.Entry(t).State = EntityState.Modified;
EFDB.SaveChanges();
//删除
EFDBModelContainer EFDB = new EFDBModelContainer();
Student s = new Student();
s.Id = 1;
Teacher t = new Teacher();
t.Id = 1;
s.Teacher = t;
EFDB.Entry(s).State = EntityState.Deleted;
EFDB.Entry(t).State = EntityState.Deleted;
EFDB.SaveChanges();
016 Linq开篇
//Linq查询 [Link]
EFDBModelContainer EFDB=new EFDBModelContainer();
var list = from u in EFDB.Student //从数据上下文集合中遍历每一项
where u.Score < 80
select u;
foreach(var item in list)
{
Console.WriteLine(item.Score);
}
//原查询
EFDBModelContainer EFDB = new EFDBModelContainer();
List<Student> slist = new List<Student>();
foreach (var item in EFDB.Student)
{
if(item.Score<80)
{
slist.Add(item);
}
}
foreach(var item in slist)
{
Console.WriteLine(item.Score);
}
017 linq分页
1 IQueryable<Student>是一个泛型接口,继承自IQueryable,
其中的IQueryProvider Provider { get; }是查询驱动器,目的是根据不同的数据源提供不同的驱动程序进行查询
2 延迟查询,在用到数据list的时候才会生成sql语句去数据库查询
3 对查询结果按Id进行排序,跳过该页前面的数据,获得当前页的几条数据
//Linq分页
EFDBModelContainer EFDB=new EFDBModelContainer();
//IQueryable<Student> list = from u in EFDB.Student
// select u;
////IQueryable<Student>是一个泛型接口,继承自IQueryable,
////其中的IQueryProvider Provider { get; }是查询驱动器,目的是根据不同的数据源提供不同的驱动程序进行查询
//foreach(var item in list)//延迟查询,在用到数据list的时候才会生成sql语句去数据库查询
//{
// Console.WriteLine(item.Score);
//}
//分页,每页4条,显示第2页
IQueryable<Student> pagelist = (from s in EFDB.Student
select s).OrderBy(i => i.Id).Skip((2 - 1) * 4).Take(4);//对查询结果按Id进行排序,跳过该页前面的数据,获得当前页的几条数据
foreach(var item in pagelist)
{
Console.WriteLine(item.Id);
}
018 Linq查询方法
//Linq查询方法
//Func<int, bool> func = i => i < 8;//泛型委托,传入int,传出bool类型
//Console.WriteLine(func(1));
//Func<string, int> func1 = i => int.Parse(i);
//Console.WriteLine(func1("1"));
EFDBModelContainer EFDB = new EFDBModelContainer();
//IQueryable<Student> slist = EFDB.Student.Where(i => i.Score < 80);
//foreach(var item in slist)
//{
// Console.WriteLine("{0},{1}", item.Name, item.Score);
//}
//Student s = EFDB.Student.FirstOrDefault();//第一条数据,如果没有,返回默认值
//Student s1 = EFDB.Student.First();//第一条数据,如果没有,报错
//Student s2 = EFDB.Student.SingleOrDefault(i => i.Id == 18);//去唯一一条数据
//Console.WriteLine(s2.Name);
IQueryable orderlist = EFDB.Student.OrderBy(i => i.Id);//排序,正序
IQueryable<string> namelist = EFDB.Student.Select(i => i.Name);//筛选同一类型Name的集合(只有Name项的集合)
foreach (var name in namelist)
{
Console.WriteLine(name);
}
list.First();//返回数据源的一个条目,没有数据值,报错
list.FirstOrDefault();//返回数据源的一个条目,没有数据值,返回默认值
list.Last();//返回数据源的最后一条数据
list.LastOrDefault();//返回数据源最后一条数据,没有数据值,返回默认值
list.Max();//最大值
list.Min();//最小值
list.OrderBy();//对数据源进行排序,正序
list.Reverse();//反转
list.Select();
list.SelectMany();//----???---
list.Single();//唯一一条数据
list.SingleOrDefault();
list.Skip();//跳过
list.SkipWhile();
list.Sum();
list.Take();//取得
list.TakeWhile();
019 EF映射
对EFDBModel.edmx文件,用XML文本编辑器打开,这个xml文件包含了所有映射秘密.
SSDL 数据库模型(保存了所有关于数据库的表的信息)
CSDL 保存应用程序的内容(包含类的属性名称等)
C-S mapping 保存有从数据库到应用程序二者之间的映射关系(C#属性的名字 数据库列的名字)
凡是继承了DbContext的类的对象,都称之为数据上下文对象。
DbContext的作用:把应用程序中的代码通过拼接指令,它可以把这些指令发送给数据库中;或者从数据库中获取数据,然后拼接生成C#的代码。
Context.tt就是文本模板文件,如添加文本模板,就是产生一个写C#语言的一个模板
我们所有生成的EF中的类都是通过这个模板里面产生的代码,当然可以修改模板,产生一些自己想要的代码
我们这个Context.tt就是根据EFDBModel.edmx模型生成对应的模板
如删掉实体类,重新保存模型后,又会重新生成实体类
图说:
首先用Linq技术
然后调用数据上下文
把Linq产生的查询通过EntityClient生成一个查询数据库的sql语句
然后sql又通过概念层、映射层、存储层的对应关系
然后最底层调用这个ADO.NETDataProviders这个操作数据库的方法
最终到数据库中拿取数据源
020 mvcvswebform
WebForm开发
缺点:
视图状态,传递大量垃圾代码,占网络带宽;
页面生成周期,中间过程非常复杂,很难在不报错的条件下找到错误原因;
前后台分离,aspx.cs还可以操作页面控件;
自动渲染的html不符合标准.
Asp.Net MVC开发
MVC是一种思想,把M V C分开,完全按照http请求、处理响应分离的标准。
基于NET平台的一种开发网站的技术
MVC是微软2009对外公布的第一个开源的表示层框架,这是微软的第一个开源项目 Mono
MVC目的不是取代WebForm开发,只是web开发的另一种选择。(公司内网做一些小功能)
021 Mvc思想
MVC 模式是一种表现模式。它将web应用程序分成三个主要组件
即:视图View 控制器Controller 模型Model
M:Model 主要是存储或者是处理数据的模型,包含了用户使用的数据(业务逻辑、数据、验证规则、数据访问等)
C:Controller 处理传入的请求,执行模型上的操作,并选择给用户的视图
V:View 把模型数据渲染成Ui,返回给用户
Controller只负责用户的请求和处理
Model只负责数据
View只负责与用户的交互
022 Mvc模拟
新建一个空网站--添加一个html(View)--添加一个ashx(Controller)--添加一个cs(Model)
context.Response.ContentType = "text/html";
//1 当接收到请求时,从Model中拿到用户所需的数据
Model m = new Model() { Name = "Rocky", Pwd = "123", Address = "北京市" };
string path = context.Server.MapPath("View.html");
string html = System.IO.File.ReadAllText(path);
//2 组织数据
string htm = html.Replace("@Name", m.Name).Replace("@Pwd", m.Pwd).Replace("@Address", m.Address);
//3 发送给浏览器
context.Response.Write(htm);
023 认识Mvc文件
添加新建项目--新建Web下的VS2012中的ASP.NET MVC4 Web应用程序MvcDemo--选择模板(基本 Razor 不创建单元测试)--
App_Data 专门存放网站的私有数据文件(不会被人访问的到)
App_Start 整个网站的一些C#类得配置信息
Content 主要是存放一些网站的样式文件
Controllers 创建控制器文件
Models 主要存放一些用户数据
Scripts 主要存放js脚本
Views 主要存放MVC中的View文件,里面保存一些视图文件
Global.asax
packages.config 记载一些记录信息
Web.config
024 ControllerAndView
在Controller中添加控制器HomeController,本质是个类,继承Controller这个基类
ActionResult动作方法,所有的请求都是通过方法处理的
public string Index()
{
return "Hello Word";
}
public ActionResult Index()
{
return View();//返回一个视图,必须在方法Index上添加视图Index
}
025 ViewBag和ViewData
ViewData["message"] = "如鹏网";//以键值对索引方式进行传递任意类型的数据,message为键
ViewBag.Time = DateTime.Now.Hour;//以动态表达式为键传递数据,Time为键
@ViewData["message"]
@ViewBag.Time
026 Razor语法简介
Razor是在视图页面内写入一种C#代码的一种方式
<ul>
@{
var arrs = new string[] { "梅西", "卡卡", "郑大世" };
foreach(var item in arrs)
{
<li>@item</li>
}
}
</ul>
@{var name = "涂菡";}
@name
@{
@:这是一段文本
<text>
也可以输出大段文本
</text>
}
@{
Layout = null;//表示没有模板页
}
027-028 HtmlHelper及补充
@{Html.BeginForm();}
<table>
<tr><td>姓名:</td><td>@Html.TextBox("txtName", "杨国", new { id = "txtName", @class = "cls" });</td></tr>
<tr><td>密码:</td><td>@Html.Password("txtPwd", "123");</td></tr>
<tr><td>性别:</td><td>@Html.RadioButton("Gender", "male", true);男 @Html.RadioButton("Gender", "female", false);女</td></tr>
<tr><td>爱好:</td><td>@Html.CheckBox("football", true);足球 @Html.CheckBox("basketball", true);蓝球 @Html.CheckBox("valleball", true);排球</td></tr>
<tr><td>隐藏域:</td><td>@Html.Hidden("hid","123")</td></tr>
<tr><td>多行文本框:</td><td>@Html.TextArea("textArea")</td></tr>
<tr><td>下拉列表:</td><td>@Html.DropDownList("mySelect", new[] { new SelectListItem() { Selected = false, Text = "一班", Value = "1" }, new SelectListItem() { Selected = false, Text = "二班", Value = "2" } }, "请选择");</td></tr>
<tr><td>多选列表:</td><td>@Html.ListBox("myList", new[] { new SelectListItem() { Selected = false, Text = "A", Value = "a" }, new SelectListItem() { Selected = true, Text = "B", Value = "b" } });</td></tr>
</table>
@{Html.EndForm();}
029 HTML扩展方法
Html的类型是HtmlHelper<TModel>,该类得父类HtmlHelper没有TextBox等方法,所以TextBox等应该是扩展方法
public static class MyExtentionMethod
{
public static MvcHtmlString List(this HtmlHelper htmlHelper, string[] listItems)//给类HtmlHelper构造一个的列表方法
{
TagBuilder tag = new TagBuilder("ul");//标签创建器
foreach(string item in listItems)
{
TagBuilder itemTag = new TagBuilder("li");
itemTag.SetInnerText(item);
tag.InnerHtml += itemTag.ToString();//把内标签li累加到外标签ul上//--???---
}
return new MvcHtmlString(tag.ToString());
}
}
@Html.List(new[] { "卡卡", "郑大世", "梅西" });
//使用时需要引用扩展方法所在的命名空间
例子2:
namespace Mvc_Demo.Common { public static class MyExtenMethod { /// <summary> /// HTML的<ul>标签 /// </summary> /// <param name="htmlhelper"></param> /// <param name="list">可以遍历的任意类型的 集合或数组</param> /// <returns>"<ul>"标签</returns> public static MvcHtmlString Ul(this HtmlHelper htmlhelper, IEnumerable<object> list) { TagBuilder tag = new TagBuilder("ul"); //初始化一个标签 foreach(var item in list) { TagBuilder tagLi = new TagBuilder("li"); tagLi.SetInnerText(item.ToString()); tag.InnerHtml += tagLi.ToString(); //内标签附加到外标签的innerHtml中 } return new MvcHtmlString(tag.ToString()); } } }
030 Login
@using(Html.BeginForm()){} 取代@{Html.BeginForm();}服务器,从而不需要闭合标签
@using(Html.BeginForm())
{
<table>
<tr><td>姓名:</td><td>@Html.TextBox("txtName");</td></tr>
<tr><td>密码:</td><td>@Html.Password("txtPwd");</td></tr>
<tr><td><input type="submit" value="提交" /></td></tr>
</table>
}
@Html.ActionLink("登录","Login","Home")
两种不同的提交方式Get、Post,在同一方法名得不同方法中处理
[HttpGet]
public ActionResult Login()//Get请求,登录展示
{
return View();
}
[HttpPost]
public ActionResult Login(string s)//Post请求,登录提交
{
string name = Request.Form["txtName"];
string pwd = Request.Form["txtPwd"];
return View();
}
031 获取表单的值
在MVC中获得表单提供的值有三种方式:
//1 通过表单的请求获得值
[HttpPost]
public ActionResult Login(string s)//Post请求,登录提交
{
string name = Request.Form["txtName"];
string pwd = Request.Form["txtPwd"];
return View();
}
//2 把表单提供的数据做成集合,通过集合的索引获得值
[HttpPost]
public ActionResult Login(FormCollection collection)
{
string name = collection["txtName"];
string pwd = collection["txtPwd"];
return View();
}
//3 通过方法的参数获得值,参数必须和表单名字一致
[HttpPost]
public ActionResult Login(string txtName,string txtPwd)
{
return View();
}
032 Entity登录
创建数据库表T_User(Id Name Pwd Phone Email Address Gender)
在Model中,(根据数据库DBFirst)添加实体数据模型(需要修改命名空间MvcDemo.Models,使与Models中的命名空间一致)
实例化数据上下文时需要引用模型的命名空间
T_User user = entity.T_User.Where(i => i.Name == txtName && i.Pwd == txtPwd).FirstOrDefault();
if(user!=null)//查询到匹配的用户
{
return View("Success");//返回一个Success页面(需要添加一个Success页面)
}
else
{
return View("Error");
}
033 强类型注册页面
登录失败转向注册页面
return View("Register",new T_User());//创建一个强类型视图,需要一个强类型的对象
创建强类型视图(如果想在视图页面用到真正存在的实体类的数据,那么需要把这个实体类的数据传递到视图页面中,使当前页面可以使用这个对象)
@model MvcDemo.Models.T_User //定义这个视图中使用哪一个实体类的对象(全局,整个类可以适用)
TextBoxFor方法,主要目的是通过强类型的对象来完成我们的表单元素
<tr><td>性别:</td><td>男 @Html.RadioButtonFor(i=>i.Gender,"male") 女 @Html.RadioButtonFor(i=>i.Gender,"female")</td></tr>
034 注册完成
1 因为强类型视图中,每一个表单项的名称就是强类型对象的属性名,MVC在接受到表单所提交的数据时,就会给我们自动产生一个该类型T_User的对象,该对象的对应属性值会被自动赋上,所以可以通过该类型对象获得表单提交的数据
2 提交那个方法,那个控制器
@using(Html.BeginForm("Register","Home"))
3 报错或其中的Gender为false,因为Gender的值为male时,与该对象的Gender类型不一致,会赋值失败或默认赋值为false,应该明确赋值为true或false
<tr><td>性别:</td><td>男 @Html.RadioButtonFor(i=>i.Gender,"true") 女 @Html.RadioButtonFor(i=>i.Gender,"false")</td></tr>
[HttpPost]
public ActionResult Register(T_User user)
{
entity.T_User.Add(user);
entity.SaveChanges();
return View();
}
035 数据展示
1 列表页面需要一个集合,但是添加的强类型是一个User类型,其中只包含了一条User数据实体,需要把这个强类型改为List<>集合
@model List<MvcDemo.Models.T_User>
2 foreach(var item in Model){..}//Model就是表示页面中强类型的对象(即集合)
3 return Redirect("/Home/List");//注册或登录成功后,重定向列表页面
4 List<T_User> list = entity.T_User.ToList();//把DbSet类型的集合转换为List类型的集合
return View(list);//传递强类型对象list
036 路由机制
在MVC中请求由ActionResult动作方法处理,所以不能写成ahsxaspx的文件形式,而应该是http://xxx/Home/Index,路由机制就是找到这个方法Index
routes.MapRoute()//定义路由
原理:用路由url格式去匹配这个地址http://xxx/Home/Index
路由是从上到下匹配,一旦匹配就不再向下匹配
//自己注册路由:
//1
routes.MapRoute("myRoute", "{controller}/{action}");
//2 有默认值的路由
routes.MapRoute("myRoute1", "{controller}/{action}", new { controller = "Home", action = "Index" });
//3 有静态片段的路由
routes.MapRoute("myRoute2", "public/{controller}/{action}", new { controller = "Home", action = "Index" });//添加了静态片段public
//4 有自定义片段的路由
routes.MapRoute("myRoute3", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = 1 });//添加了自定义片段id
//5 定义可选url片段的路由
routes.MapRoute("myRoute4", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });//自定义id片段可选
037 编辑功能
1 在Global中当Application_Start(应用程序运行起来)时,通过RegisterRoutes把我们的路由机制加载到整个网站中去
2 超链接中object routeValue,就是路由机制中的自定义片段id的值
@Html.ActionLink("编辑", "Edit", new { id=item.Id})
3 模型辅助器:把当前传过来的强类型进过推测后,自动产生一个可以编辑的界面,但是它并没有自动生成表单
@using(Html.BeginForm("Edit","Home"))
{
@Html.EditorForModel()//对强类型推测后自动产生一个可编辑页面
<input type="submit" value="保存" />
}
4 在属性上加特性,完全隐藏,编辑等不显示Id (如果在Models中User实体的Id上只加特性[HiddenInput],就会以只读的形式显示出来,)
[HiddenInput(DisplayValue=false)]
public long Id { get; set; }
5 public ActionResult Edit(long id)//接受请求后,会尝试解析字符串id为long类型
038 基本元数据
1 元数据定义:
当前所有操作都是通过模型来完成的,模型给我们提供了很多的方法,通过模板服务器产生一些自己定义、自己需要的html代码,这样省了编写html代码的一些过程
但是有的时候需要控制数据的输出,有些内容需要输出,有些不需要输出,甚至输出的名字需要修改,这个东西都称之为元数据
2 @Html.DisplayForModel()//用来展示页面
3 在属性Name上加特性[Display(Name="姓名")],就展示内容为“姓名”
在属性Pwd上加特性[DataType(DataType.Password)],展示形式为密码框,因为显示形式type是根据类型推断的
在属性Email上加特性[DataType(DataType.EmailAddress)],展示为邮箱框
[HiddenInput(DisplayValue=false)] //完全隐藏,编辑等不显示Id
public long Id { get; set; }
[Display(Name="姓名")]//控制显示的名称为“姓名”
public string Name { get; set; }
[Display(Name = "密码")]
[DataType(DataType.Password)]//控制显示方法是密码框(因为显示方式type是根据属性的类型推断的)
public string Pwd { get; set; }
[Display(Name = "邮箱")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Display(Name = "电话")]
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
039 Model验证
1 在MVC中可以直接通过模型进行验证,它给我们提供了一些特性,通过这些特性进行验证
包括非空验证、限制数据输入等
[Required(ErrorMessage="请输入姓名")]//非空验证
[Required(ErrorMessage = "请输入密码")]//------!!!----(非空后才会进行长度和格式验证)
[StringLength(6,MinimumLength=3)]//字符串(密码)长度最大为6,最小为3
[Required(ErrorMessage = "请输入邮箱")]
[RegularExpression(".+\@.+\..+")]//用正则表达式验证邮箱
[Range(10,20)]//验证数字的范围
2 回到视图页面需要输出验证信息
@Html.ValidationMessageFor(i=>i.Name)
3 在控制器中的Register中如果前端验证通过才进行添加
if (ModelState.IsValid)//ModelState.IsValid存取客户端提交上的数据是否全都通过了验证----???---
{
entity.T_User.Add(user);
entity.SaveChanges();
return Redirect("/Home/List");//注册成功后,也重定向列表页面
}
else
{
return View();
}
[HttpGet]
public ActionResult Register()
{
return View(new T_User());//按理说展示请类型页面时需要传递实体的,但是这里不传实体也是可以的(后面不传也是可以的)
//return View();//也可以,强类型页面所做的事情就是将 某个类型传递到页面中使用, 如果页面中不需要使用这个类型“的实体”,就不需要传递这个参数,
}
040 异步删除
因为删除不需要跳转页面,只是局部刷新当前列表页面,所以需要异步ajax删除
@Html.ActionLink("删除","Delete",new {id=item.Id},new {id=item.Id,@class="del"})//ajax需要class或name,和id
$(function () {
$(".del").each(function () {
$(this).click(function () {
var id = $(this).attr("id");
$.post("/Home/Delete", { id: id }, function (data) {
//alert(data);
if (data.status == "ok") {
window.location.reload();
return;
} else {
alert("删除失败");
}
},
"json"
);
return false;//阻止超链接行为的发生
});
});
});
public ActionResult Delete(long id)
{
T_User u = entity.T_User.Where(i => i.Id == id).SingleOrDefault();
entity.Entry(u).State = EntityState.Deleted;
entity.SaveChanges();
//return Content("ok");
return Json(new { status = "ok", msg = "成功" });//Json()把匿名类得对象转json
}
041 layout
原理:
模板页引用当前子页面(即当前引用模板的页面)的Section Header{...} ;
模板页应用分部视图Partial1.cshtml .
1 模板页,用于布局,放在Views/Shared/_Layout.cshtml
引用当前网站的web样式表,js脚本,占位符,当前子页面的代码块,分布视图
在模板中:
@Styles.Render("~/Content/css") //引用当前子页面的样式表
@Scripts.Render("~/bundles/modernizr") //引用当前子页面的js脚本
@RenderBody() //占位符,填充当前子页面的内容
@RenderSection("scripts", required: false) //引用当前子页面的代码块
2 添加一个视图(子页面),当前子页面套用了哪一个模板页(_Layout.cshtml),在子页面写一些html或C#代码,将来在模板页可以引用到子页面写得这些代码
子页面代码块:
@section Header{
@foreach()
{
<div style="float:left;padding:5px">
@Html.ActionLink(item,item)
}
}
@section Footer{
<h3>尾</h3><h3>尾巴</h3><h3>只有尾</h3>
}
模板中引用:
@RenderSection("Header") //引用当前子页面的代码块
@RenderSection("Footer");
3 分布视图:
点击Home添加视图--创建分布视图Partial1--空白的分布视图内容随意--
在模板中引用分布视图:
@Html.Partial("Partial1") //将来返回一个html字符串
@{Html.RenderPartial("Partial1");} //将来返回结果送到输出流,然后回传浏览器
042 异步提交表单
在MVC中使用Ajax技术进行异步操作
在视图进行的Ajax操作都可以通过调用AjaxHelper对象的函数来完成(MVC把对异步的操作都封装到了AjaxHelper类中)
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> //微软进行封装了的进行异步操作的文件
<script type="text/javascript">
function begin() {
alert("开始ajax异步提交了哦");
}
function success(data) {
alert(data.msg);
}
</script>
//Ajax异步表单提交
@using(Ajax.BeginForm(new AjaxOptions(){ //Ajax异步表单提交:通过设置类AjaxOptions的对象的属性来完成操作
Confirm="您确定要提交吗?",//提交请求之前的提示信息
Url="/Home1/Index",//提交请求的url地址
HttpMethod="post",//提交方式
OnSuccess="success",//成功提交后的js回调函数
OnBegin="begin" //提交之前立即执行的js函数
}))
{
<table>
<tr><td>@Html.Label("姓名:")</td><td>@Html.TextBox("txtName")</td></tr>
<tr><td>@Html.Label("密码:")</td><td>@Html.Password("txtPwd")</td></tr>
<tr><td colspan="2"><input type="submit" value="提交" /></td></tr>
</table>
}
043 Mvc总结
MVC课程回顾
MVC三个组件的感念:
Model,模型,是领域模式;
View, 视图,展示数据的模块
Controller,控制器,组织业务逻辑,从model中获取数据并将数据交给view显示。
WebForms Vs MVC
MVC优点:
1 很容易将复杂的应用分成M、V、C三个组件模型
通过model、view、controller有效的简化了复杂的架构,体现了很好的隔离原则;
2 因为没有使用server-based forms,所以我们程序员控制的更加灵活,页面更加干净;
3 可以控制生成自定义的url,对于seo友好的url更是不在话下;
4 强类型View实现,更安全、更可靠、更高效;
5 让web开发可以专注于某一层,更利于分工配合适用于大型架构开发;
6 很多企业已经使用了MVC作为项目开发框架,招聘明确要求熟悉MVC开发模式,我现在做的项目架构就是mvc+ef+wcf+...
MVC != 三层架构
MVC是一种思想,是一种开发网站的框架的思想,是表现模式
S三层是架构模式
表示层 View---Controller
业务逻辑层 --Model--
数据库接口层
扩展学习:
Asp.Net MVC中使用Ajax:Jauery方式,微软提供的Ajax form方式(还可以加上一个jquery验证)
Asp.Net MVC中服务器验证和客户端的验证
Asp.Net MVC中过滤器的使用
Asp.Net MVC中的测试
Asp.Net MVC部署