Visual Studio 2010 --MVC2.0 只有aspx视图引擎
Visual Studio 2012 --MVC3.0和MVC4.0 aspx和Razor视图引擎
Visual Studio 2013 --MVC4.0 aspx和Razor视图引擎
Visual Studio 2015 --MVC5.0 只有Razor视图引擎
MVC模式简介
MVC模式两种理解:一种是表现模式,另外一种是架构模式。
它将应用程序分为三个主要组件即:视图(View),控制器(Controller),模型(Model)
M:Model主要是存储或者是处理数据的组件
Model其实是实现业务逻辑对实体类相应数据库操作,如:CRUD。它包括数据、验证规则、数据访问和业务逻辑等应用程序信息。ViewModel:视图模型
V:View是用户接口层组件。主要是将Model中的数据展示给用户,ASPX和ASCX文件被用来处理视图的职责。
C:Controller处理用户交互,从model中获取数据并将数据传给指定的View
[ASP.Net的两种开发方式]
WebForm的开发方式
1.服务器端控件
2.一般处理程序+Html静态页+Ajax
3.一般处理程序+Html模板
ASP.Net MVC的开发方式
2009年第一个开源项目版本发布
更加简洁,更加接近原始的“请求-处理-响应”
更加开发、更多的新的特点、社区活跃
不会取代WebForm
底层跟WebForm都是一样的。管道上不同的处理而已
*Controller放到controllers文件夹中,并且命名方式以Controller结尾
*每个Controller都对应View中的一个文件夹,文件夹的名称跟Controller名相同
*Controller中的方法名都对应一个View视图(非必须,但是建议这么做),而且View的名字跟Action的名字相同
*控制器必须是非静态类,并且要实现IController接口
*Controller类型可以放到其他项目中
[视图的相关约定]
*所有的视图必须放到Views目录下
*不同控制器的视图用文件夹进行分割,每个控制器都对应一个视图目录
*一般视图名字跟控制器的Action相对应(非必须)
*多个控制器公共的视图放到Shared
[ViewData]传递数据载体
*ViewData是Controller的属性,此属性是继承ControllerBase而来。
*ViewPage下也有一个ViewData的一个属性
*控制器的Action方法执行完成后,返回ViewResult,然后MVC框架会执行ExecuteResult方法时,Controller中的ViewData数据传递给ViewPage类,
其实就是把Controller的ViewData赋值给ViewPage页面的ViewData属性
*ViewBag传递数据(原理参考ViewData)
MVC强类型视图
1:view中把 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage
2:后台给ViewData.Model赋值
3:前台 就可以使用Model.Id 等等
强类型的HtmlHelper
<%: Html.TextBoxFor(u=>u.UserName) %>
硬编码的HtmlHelper
<%:Html.TextBox("UserName") %>
[Html.Encode]
<%:%> 相当于<%= Html.Encode()%>
推荐大家使用<%:%>,方便简洁
输出特殊字符比如
HtmlString和MvcHtmlString可以屏蔽冒号的编码化
Html.Raw():也可以把字符串原封不动的输出到页面上,避免被编码化。
原样输出:
<%:Html.Row("")%>
<%: new HtmlString("")%>
<%: new MvcHtmlString("")%>
[HtmlHelper扩展]
扩展方法的三要素:静态类、静态方法、this关键字
使用方法是: 在视图上。引用静态类所在的命名空间 (或者直接把静态类的命名空间修改为HtmlHelper类的命名空间)
1 namespace System.Web.Mvc 2 { 3 public static class MyHtmlExt 4 { 5 ///6 /// 原样输出 7 /// 8 /// 9 /// 10 /// 11 public static string Mylabel(this HtmlHelper htmlHelper, string value) 12 { 13 return string.Format(" {0}
",value); 14 } 15 16 ///17 /// 编码化 18 /// 19 /// 20 /// 21 /// 22 public static MvcHtmlString MyHtmlLable(this HtmlHelper htmlHelper, string value) 23 { 24 return new MvcHtmlString(string.Format(" {0}
", value)); 25 } 26 } 27 }
关于控制器Action参数的赋值:
//Action在执行之前,MVC框架会自动的将请求中的数据装配到Action的参数在里面去
参数Id通过MVC路由规则传递参数,参数为非Id则通过QueryString方式进行传递参数
双向数据装配
1:控制器通过ViewData容器把数据传递到View之后,View在渲染Html标签的时候会自动从ViewData中获取数据进行填充标签
2:表单提交到控制器的时候,执行控制器的Action之前会自动将表单中的内容填充到方法的参数或者参数的属性里面去
->自动装配
(1)在Action的形参处,使用与路由规则中同名的参数,即可以完成数据接收
(2)在页面跳转中,action的形参的名称,与页面提交的key的名称相同
(3)将action的多个参数完成封装,要求提交的key的名称与action形参对应类型的属性同名
[Razor引擎]
在MVC3.0版本的时候(Visual Studio 2012),微软终于引入了第二种模板引擎:Razor。
Razor文件类型:Razor支持两种文件类型,分别是.cshtml 和.vbhtml,其中.cshtml 的服务器代码使用了c#的语法,.vbhtml 的服务器代码使用了vb.net的语法。
Razor在减少代码冗余、增强代码可读性和vs 智能感知方面,都有着突出的优势(C#代码和HTML代码可以进行混编)
@字符是Razor中的一个重要符号,它被定义为Razor服务器代码块的开始符号,可以使用@{code}来定义一段代码块
Demo: @DateTime.Now.ToString("yyyy-MM-hh")
输出原生的字符串:@Html.Raw(html),例如:@Html.Raw("
Razor
")HtmlString类型和MvcHtmlString类型字符串输出,例如:IHtmlString html=new HtmlString("文本");
Razor服务器端注释为:@* 注释内容 *@
[控制器详解]
控制器三个职责:
1:处理跟用户的交互
2:处理业务逻辑的调用
3:指定具体的视图显示数据,并且把数据传递给视图
*控制器的约定:
必须非静态类
必须实现IController接口
必须以Controller为结尾
*在Action中可以访问HttpContext中所有的相关数据:比如:Session、Cookie、也可以设置响应,总之跟WebForm中Page类能做的,在Action中都能做。
-》Action:本质就是方法,可以重载
针对于Action构成重载的两个要求:(1)参数不同;(2)必须指定请求方式
可以使用[HttpPost][HttpGet]设置行为约束
参数接收:(1)使用Request对象;(2)自动装配
-》Action参数自动装配的条件
要求参数的键的名字,与方法的形参的名字相同
在自动装备时,会根据形参的类型,进行类型转换
返回结果:面向抽象编程,类型为ActionResult,而实际返回是一个ActionResult的子类对象
常用的ActionResult的子类:ViewResult,ContentResult,RedirectResult,JsonResult,FileContentResult
-》Controller可以写到一个项目中,也可以写到多个项目中
[深入讲解Controller]
Controller负责将获取Model数据并将Model传递给View对象,通知View对象显示。
一个Controller可以包含多个Action。每一个Action都是一个方法,返回一个ActionResult实例
一个Controller对应一个XxController.cs控制文件,对应在View中有一个Xx文件夹。一般情况下 一个Action对应一个aspx页面
[MapRoute]
Global.asax.cs文件中定义了路由的识别规则
1 routes.MapRoute( 2 name: "Default", // 路由名称,作为路由规则的key,一定不能重复 3 url: "{controller}/{action}/{id}", // 带有参数的URL,请求后台URL规则 4 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 5 );
//路由规则:
1:可以有多条路由规则
2:路由规则是有顺序的
MapRoute()方法
MapRoute( string name, string url);
MapRoute( string name, string url, object defaults);
MapRoute( string name, string url, string[] namespaces);
MapRoute( string name, string url, object defaults, object constraints);
MapRoute( string name, string url, object defaults, string[] namespaces);
MapRoute( string name, string url, object defaults, object constraints, string[] namespaces);
MapRoute参数介绍
【name参数】: 规则名称, 可以随意起名.不可以重名,否则会发生错误:路由集合中已经存在名为“Default”的路由。路由名必须是唯一的。
【url参数】: url获取数据的规则, 这里不是正则表达式, 将要识别的参数括起来即可, 比如: {controller}/{action}
最少只需要传递name和url参数就可以建立一条Routing(路由)规则.比如实例中的规则完全可以改为:
routes.MapRoute( "Default", "{controller}/{action}");
【defaults参数】: url参数的默认值.如果一个url只有controller: localhost/home/
而且我们只建立了一条url获取数据规则: {controller}/{action}
那么这时就会为action参数设置defaults参数中规定的默认值. defaults参数是Object类型,所以可以传递一个匿名类型来初始化默认值:
new { controller = "Home", action = "Index" }
实例中使用的是三个参数的MapRoute方法:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults );
【constraints参数】:用来限定每个参数的规则或Http请求的类型.constraints属性是一个RouteValueDictionary对象,
也就是一个字典表, 但是这个字典表的值可以有两种:
1.用于定义正则表达式的字符串。正则表达式不区分大小写。
2.一个用于实现 IRouteConstraint 接口且包含 Match 方法的对象。
通过使用正则表达式可以规定参数格式,比如controller参数只能为4位数字: new { controller = @"\d{4}"}
[Url路由总结]
-》与路由相关类型:
路由规则Route:制定路由的名称Name、url规则、默认值Default、约束constraints
路由数据RouteData:当前上下文匹配到某个路由规则后,得到的一个对象
路由集合RouteCollection:存放路由规则对象的集合
路由表RouteTable:包含一个静态的RouteCollection类型的属性
简单总结:
(1)Routing规则有顺序(按照添加是的顺序), 如果一个url匹配了多个Routing规则, 则按照第一个匹配的Routing规则执行.
(2)由于上面的规则, 要将具体频道的具体页面放在最上方, 将频道首页 和 网站首页 放在最下方.
(3) {*values} 表示后面可以使任意的格式.
【关于测试Routing】
使用RouteDebug辅助类
在Global.asax添加如下代码:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
//路由调试,放在所有代码之后
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
}
【MVC验证】
*.NET框架中的System.ComponentModel.DataAnnotations命名空间包括了众多可为你所用的内置验证特性,
介绍用的最多的其中的四个:[Required],[StringLength],[Range],[RegularExpression]
*定义自己的定制验证特性,然后应用它们。你可以通过继承自System.ComponentModel.DataAnnotations命名空间中的ValidationAttribute基类,定义完全定制的特性。
*属性ErrorMessage:指定错误提示信息
-》使用Html.ValidationMessageFor(***)显示校验错误信息
-》在服务器端使用ModelState.IsValid判断前台是否验证成功
[服务器端校验]只需要在Action中校验:ModelState.IsValid属性即可。true就是校验通过,false就是不通过。
-》伙伴类:定义的类之间,可以共享元数据 [MetadataType(typeof(CustomerFriend))]
Metadata是.NET平台的核心灵魂 - leooelg 链接: http://pan.baidu.com/s/1jHBplhs 密码: r7i2
-》操作步骤:
(1)生成类CutomerInfo
(2)定义部分类CustomerInfo1
(3)定义基友类CustomerFriend,要求成员的签名与CustomerInfo中一致
(4)为CustomerInfo1中的类添加基友特性MetadataType(typeof(CustomerFriend))
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Web; namespace MVCMetadataDemo.Models { [MetadataType(typeof(CustomerFriend))] public partial class CustomerInfo { public int Id { get; set; } } //部分类 实际情况下 应该位于不同的*.cs文件中,这里只是演示Demo public partial class CutomerInfo { public string CustomerName { get; set; } } public class CustomerFriend { [Required(ErrorMessage="必填字段")] public string CustomerName { get; set; } } }
*要使用[客户端校验],必须引入Js脚本支持(JQuery的校验)
[
]
*添加语句 <% Html.EnableClientValidation(); %>(MVC3、4中默认开启)
*WebConfig中可以设置全局客户端校验是否开启或者关闭
【JQuery Ajax】
MVC4 AspNet MVC下的Ajax / 使用JQuery做相关的Ajax请求
跟普通的WebForm的开发方式都一致的
Url地址不同点:请求的是Controller下的Action
在使用Json返回JsonResult时注意要将第二个参数设置允许Get提交方式:return Json("",JsonRequestBehavior.AllowGet)
在Ajax开发中要注意Ajax方法体内的参数设置正确
提交方式要跟Action打的标签一致
【Asp.net MVC Microsoft Ajax】
MVC4 AspNet MVC下的Ajax / 使用微软提供的Ajax请求脚本
*将微软提供的脚本引入到页面中
*注意引用的顺序
*Ajax.BeginForm没有提供闭合的方法,请使用Using配合关闭
*AjaxOptions参数的设置
*SuccessMethod只是提供提醒,并没有数据的传递
[过滤器详解]
项目大一点总会有相关的AOP面向切面的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中呢Action在执行前或者执行后我们想做一些特殊的操作
(比如身份验证,日志,异常,行为截取等),而不想让MVC开发人员去关心和写这部分重复的代码,那我们可以通过AOP截取实现,
而在MVC项目中我们就可以直接使用它提供的Filter的特性帮我们解决,不用自己实现复杂的AOP了。
-》一共有4种过滤器
[身份验证过滤器:AuthorizeAttribute]:Authorzation filter: 一般用来实现身份校验,在执行实际的action之前,先执行指定的身份验证过滤器
[Action过滤器:ActionFilterAttribute] :
Ps:新建一个类 MyActionFilterAttribute:ActionFilterAttribute
ActionFilterAttribute 默认实现了IActionFilter和IResultFilter。
而ActionFilterAttribute是一个Abstract的类型,所以不能直接使用,因为它不能实例化,所以我们想使用它必须继承一下它然后才能使用
案例:Action过滤
AttributeUsage特性用于设置标签
[AttributeUsage(AttributeTargets.All,AllowMultiple = True)] 标记在类的级别 //AllowMultiple = true; 允许多个标签同时都起作用
Gloable Filte允许我们设置全局过滤器
[Result过滤器:ResultFilterAttribute]:
[异常过滤器:HandleErrorAttribute]:当我们Mvc站点出现了异常的时候会自动执行异常过滤器里面的方法[继承与HandleErrorAttribute]。
Ps:新建一个类:MyExceptionFilterAttribute:HandleErrorAttribute
要使用自定义异常处理,需要使用在web.config中为system.web添加
重新定义一个类,后缀名称为Attribute,继承自HandleErrorAttribute
重写OnException()方法
关键:将filterContext.ExceptionHandled=true,建议不要删除base.***代码
使用filterContext.Result=new RedirectResult("/Error.html");
[区域详解]
Asp.Net MVC提供了区域的功能,可以很方便的为大型的网站划分区域。
可以让我们的项目不至于太复杂而导致管理混乱,有了区域后,每个模块的页面都放入相应的区域内进行管理很方便。
在项目上右击创建新的区域
区域的功能类似一个小的MVC项目,麻雀虽小五脏俱全,有自己的控制器、模型、视图、路由设置
区域的路由设置是最优先的
-》在项目中添加一个区域,就相当于增加了一个子项目,管理更加方便
-》注意:需要将区域中的路由规则添加到主的路由规则中
-》在项目的Global文件中第一句注册:AreaRegistration.RegisterAllAreas();
说明:注册代码在添加区域后会自动添加到Global中
[模板页]
-》使用模板,就是做好一个页面,在里面空出来区域,以便在子页面中填充,快速完成页面开发
-》对于aspx引擎,使用母版页
-》对于razor引擎,使用布局
模板页必须放到共享的文件夹中。
WebForm视图引擎的模板页跟之前的没有什么区别。
Razor引擎引入 渲染区域的概念
所有页面启动的时候ViewStart文件先执行
Demo:Razor引擎模板页 RanderBody和RenderSection
1 DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <meta name="viewport" content="width=device-width" /> 6 <title>@ViewBag.Titletitle> 7 @Styles.Render("~/Content/css") 8 @Scripts.Render("~/bundles/modernizr") 9 head> 10 <body> 11 @RenderSection("Header",false) 12 <h1>这里是Layout模板页h1> 13 @RenderBody() 14 15 @Scripts.Render("~/bundles/jquery") 16 @RenderSection("scripts", required: false) 17 body> 18 html>
Razor 测试视图页面,引用Layout.cshtml 模板页
1 @{ 2 ViewBag.Title = "Index2"; 3 } 4 5 <h2>Index2h2> 6 <h1>Razor Index2 子页面h1> 7 8 @section Header{ 9 <h1>这里是Header部分h1> 10 }
[WebAPI]
淘宝开放平台、腾讯开放平台
WebService和WCF复杂不够灵活
MVC4.0中发布了第一个版本的WebAPI
WebAPI:轻巧、方便就是Http请求
[Web API CRUD] [HTTP请求方法]
CURD 是指 Create 、 Update 、 Read 、 Delete 四个简单的数据库操作, 通常大多数 Web 服务也通过 REST 风格的服务提供这些操作。
HTTP 的四个主要方法 (GET, PUT, POST, DELETE) 按照下列方式映射为 CURD 操作:
GET 用于获取 URI 资源的进行展示, GET 操作不应对服务端有任何影响;
PUT 用于更新 URI 上的一个资源, 如果服务端允许, PUT 也可以用于新建一个资源;
POST 用于新建 资源, 服务端在指定的 URI 上创建一个新的对象, 将新资源的地址作为响应消息的一部分返回;
DELETE 用于删除指定的 URI 资源。
Get:一般用作查询,多次操作得到结果一致
Post:一般用于修改、添加多次重复操作得到结果不一致。
Put:一般用于修改,多次操作得到结果一致。
Delete:一般用于删除数据,多次操作得到结果一致。
参考代码:链接:http://pan.baidu.com/s/1bnU9mj1%20 密码:co5u