ASP.NET MVC 知识点
前言:前几天要准备一个演讲,所以准备了MVC的一些基本的东西,以前也使用过MVC,但是只是使用,而不是去了解,所以趁着这个机会好好的把别人的MVC视频看了一下(是一个微软的MVP会员发布的视频,相信有些人都看过),整理除了这个笔记,共享一下子,基本MVC的所有东西都介绍了,但是都是很基础的东西。本来打算一篇发表完的,但是发现东西有点多,所以分成了两篇博客!
什么是ASP.NET MVC
(1) ASP.NET MVC是微软官方提供的MVC模式编写ASP.NET Web应用程序的一个框架
(2)MVC是微软继ASP.NET WebForms后的有一种开发方式,并非替代方式!
(3)官方网站:http://www.asp.net/mvc
(4)源码网站:http://aspnet.codeplex.com/wikipage?title=MVC
ASP.NET MVC的特点
(1) 分离任务,耦合度很低
(2)可扩展能力很高
(3)强大的URL重写(路由)机制
(4)兼容ASP.NET现有的技术
(5)开源
ASP.NET MVC的优点
(1) 通过把项目分为MOdel,View和Controller,使得复杂项目更加容易维护
(2)没有使用ViewState和服务器表单控件,可以更加方便的控制应用程序的行为(可以说回归了原始状态)
(3)应用程序通过Controller来控制程序请求,可以提供丰富的url重写
(4)支持测试驱动开发
(5)在团队模式下表现得更加出众
为什么我们需要ASP.NET MVC
(1) 关注点分离
(2)高可扩展性
(3)更好的可测试性
(4)更好的URL重写
(5)更好的性能
(6)更加灵活的HTML代码控制
ASP.NET MVC1
(1) 经过漫长的Preview和2个RC版本后,2009年3月,微软正式发布了ASP.NET MVC1
(2)这时微软官方在MVC领域的第一个WebApplication框架,带来了与WebForm几乎不同的开发理念
(3)但由于某些原因该版本缺失了Area等关键技术点,以至于用该版本开发复杂的MVC Web应用时会有诸多困难
ASP.NET MVC2
(1)在1.0发布后不到1年时间,ASP.NET MVC2正式发布
(2)2010年4月12日发布了VS2010和Visual Web Developer 2010正式版中内置了对ASP.NET MVC2的扩展
(3)ASP.NET MVC2该我们带来了众多期待已久的功能:如:强类型的HTML Helper,数据验证,自定义模版,Area,异步Controller等等
(4).NET 4的新技术,也给ASP.NET MVC2应用开发带来了一些不错的新体验,如:dynamic类型,带有默认值得方法参数等。
为什么需要ASP.NET MVC3?
(1) ASPX视图中充斥着<%...%><%...%><%...%>
(2)Action过滤器无法全局
(3)对404,301,302等的http响应状态,缺乏对应的ActionResult类型
(4)缺乏模型(Model)数据验证的直接支持
(5)对依赖注入(DI),控制反转(IoC)支持不够好
(6)不支持Grid
(7)ViewData用起来有些麻烦(使用dynamic类型替代)
ASP.NET MVC3
(1) 增加Razor视图引擎;支持多视图引擎
(2)全局的Action过滤器
(3)新的ViewBag属性(dynamic类型),原来是ViewData
(4)新的ActionResult类型
(5)Model Validation(Model的验证)
(6)JSON绑定支持
(7)dependency Injection(注入依赖)
(8)HTML5,CSS3
(9)部分也的输出缓存
(10)HtmlHelper的增强
(11)NuGet(VS2010环境继承的)
Razor视图引擎
(1) 使用@代替<% %>
1)语法简单清晰
2)容易学习
3)VS2010智能提示和语法着色
(2)全局设定默认布局等项目
全局的Action过滤器
(1) 3.0以前的写法
[HandleError]
public class HomeController : Controller
{
......
}
(2)3.0以后的写法:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
新的ActionResult类型
(1) HttpNotFoundResult
404
(2)RedirectResult
302\301
(3)HttpStatusCodeResult
自定义Http状态码
Model Validation
(1) 自验证
(2)客户端验证
->默认启用客户端验证
(3)远程验证
Razor视图引擎概述
(1) ASP.NET MVC 3自带了一下视图引擎
1)ASPX
2)Razor
(2)ASP.NET MVC 3支持多视图引擎机制
(3)可以在您指定的项目中自定默认的视图引擎
1)MVC3中自由的上述引擎
2)Spark
3)Nhaml
4)Ndjango
5)自己定义的视图引擎
(4)Razor视图引擎是对以代码为焦点的方法实现
(5)特点
1)简介,富于表现,流畅
->尽量减少编写一个视图模版所需要敲入的字符数,实现快速流畅的编程工作。
->不必为了明确标记出服务模块的开始和结束而中断编程,Razor解析器能从你的代码中自动推断出来
2)易于学习
->熟悉现有的编程语言和HMTML技能就能快速学会
3)可以在任何文本编辑器中工作
4)VS2010对其增加了智能提示
5)支持单元测试
(6)简介和流畅的对比
1)ASPX引擎
<%foreach(var p in products){%>
- <%=p.Name%>($<%=p.Price%>)
<%}%>
2)Razor引擎
@foreach(var p in products){
- @p.Name($@p.Price)
}
伟大的@
(1) Razor中服务器端代码段的起始位置均使用@符号作为开始
1)ASPX引擎
<%
int x=12;
string name="韩迎龙";
%>
2)Razor引擎
@{
int x=12;
string name="韩迎龙";
}
(2)渲染输出
1)经过HTML编码(放置被攻击)
1)ASPX引擎
<%:model.Message%>
2)Razor引擎
@model.Message
2)未经HTML编码
1)ASPX引擎
<%=model.Message%>
2)Razor引擎
@Html.Raw(model.Message)
(3)代码和标记混合
1)ASPX引擎
<%foreach(var item in items){%>
<%:item.Prop%>
<%}%>
2)Razor引擎
@foreach(var item in items){
@item.Prop
}
(4)代码和纯文本混合
1)ASPX引擎
<%if(foo){%>
Plain Text
<%}%>
2)Razor引擎
@if(foo){
Plain Text
}
@if(foo){
@:Plain Text
}
(5)标签式一个Razor特殊处理的元素,Razor将块内部内容视为内容块,不呈现包含那些内容的标签
(这意味着只呈现内部内容,不呈现标签本身)。这使呈现没有被HTML元素包装的多行内容块变得方便
(6)表达式与文本混合
1)ASPX引擎
Hello <%:title%>.<%:name%>
2)Razor引擎
Hello @title.@name
(7)Email地址
1)hyl934532778@live.cn
Razor可以自动识别Email地址而不作为服务器端代码执行
(8)两个连续的@@符号会被渲染成一个@符号
I Hava A Dream,@@Kencery
(9)显示渲染输出
1)ISBN@(isbnNumber)
2)当要渲染输出的代码@前无空格或标记位时,我们需要使用小括号继续您显示的渲染输出
(10)服务器端注释
1)ASPX引擎
<%
I Have a Dream
%>
2)Razor引擎
@*
I Have a Dream
*@
(11)渲染输出动态方法
1)对于动态方法返回值之类的输出我们使用小括号将代码闭合起来即可
@(MyClass.MyMethod())
(12)创建Razor委托
1)我们通过创建Razor委托来复用一些视图逻辑
@{
Func<dynamic,object> b=
@@item
}
@b("Bold this")
(13)内容中混合代码
@foreach(var p in products){
-
@p.ProductName
@if(p.unitsInStock==0){
@:(Out of stock)
}
else if(p.unitsInStock<4){
@:(only @p.unitsInStock Left!)
}
}
(14)多行内容的混合代码
1)内容在html标记闭合中时
@if(p.unitsInStock==0){
Line one of Content
Line two of Content
Date is: @DateTime.Now
Line four of Content
}
(15)多行内容混合代码
1)内容外部没有html标记包装时
1)@if(p.unitsInStock==0){
@:Line one of Content
@:Line two of Content
@:Line four of Content
}
2)@if(p.unitsInStock==0){
Line one of Content
Line two of Content
Date is: @DateTime.Now
Line four of Content
}
为什么需要布局页面
(1) 没有使用布局页时,每个页面中将大量的重复我们的核心网站布局代码
1)代码冗余
2)不利于管理
3)不利于后期的修改和维护
Razor的布局
(1) 不需要使用专门的.master文件,而统一使用.cshtml(VB中为.vbhtml)文件
1)布局文件名通常采用类似_Layout.cshtml的名字
(2)@RenderBody()用于标识布局页中可替换内容的主题部分
(3)内容页中通过给页面的Layout属性赋值实现指定布局(模版)页的文件路径
@{
Layout="~/Views/Shared/_Layout.cshtml";
}
布局页的预设可布局区域
(1) 通过使用@RenderSection在布局页中预设一些区域,用于在内容页中使用
1)@RenderSection("head",false)
->第一个参数是Section的名字
->第二个尝试使用来设定是否为必须填充内容的区域
->上述代码的含义是生命一个名字为head的非必需的内容区域
(2)内容页中通过@section head{...}的方式向名为head的section中填充内容
_ViewStart文件
(1) 在项目项目\视图文件夹下添加一个名为
_ViewStart.cshtml(或VB的_ViewStart.vbhtml)的文件
(2)该文件用来定义想要在每次视图呈现开始时执行的通用视图代码,比如我们可以在该文件中声明默认的布局属性
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
(3)因为这段代码在每个视图开始的时候执行,我们不需要再任何单个视图文件中显示设置布局(除非我们想要覆盖上面的默认值).
ASPX视图向Razor视图的转换
(1) 手写一个文件一个文件的修改?
1)坑爹啊
(2)自己写代码用正则表达式转换??
1)正则表达式功底不够好
(3)那就用著名的telerick团队打造的RazorConverter吧!
https://github.com/telerik/razor-converter
1.ASP.NET MVC请求过程
1
2.Controller
(1) 控制器在ASP.NET MVC中扮演着处理客户端请求的角色
1)必须实现System.Web.Mvc.IController接口
->通常直接继承System.Web.MVC.Controller类
2)必须要以Controller结尾
3)通过不同的Action来处理具体的客户端请求
3.Action
(1) 是指在继承了System.Web.Mvc.Controller类中所定义的返回值的类型可以兼容
(2)ActionResult方法
namespace MvcApplication.Controllers
{
public class HomeController:Controller
{
public ActionResult Index()
{
ViewBag.Message="韩迎龙";
return View();
}
}
}
(3)ASP.NET MVC3的ActionResult
(4)注意事项
1)能够通过URL访问的Action必须是公有(Public)方法
2)如果标记了[NonAction]属性,这不能通过URL访问该Action
3)默认,Action得方法名就是Action名(通过URL访问的名称),如有特殊需求也可通过[ActionName("OtherActionName")]标记出特定的Action名
4)我们可以通过[HttpPost][HttpGet]等来区分处理不同的请求动作的同名Action
4.ASP.NET Routing 路由,过滤器
(1) ASP.NET Routing模块(Module)的责任是将传入的客户端(浏览器)请求映射为特定的MVC Controller Actions
(2)路由机制
1)路由引擎 -映射URLS到Controlller
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
2)/Products/Detail/8
routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
);
public class ProductsController:Controller
{
public ActionResult Details(int id)
{
return View();
}
public ActionResult Edit(int id)
{
return View();
}
}
5. MVC3中Routing变更
(1) 从System.Web.Routing3.5程序集中转移到了System.Web 4程序集中,成为了基础服务的一部分。
(2)在ASP.NET 4中Routing的Module被注册在根Web.Config中,不需要你在自己的应用程序中的Web.Config中另行注册了
(3)UrlRoutingModule处理的事件减少了一个,仅处理PostResolveRequestCache事件
(4)HttpRequest新增加了一个RequestContext属性
(5)增加了PageRouteHandler,支持WebForm路由功能
(6)RouteCollection中增加了4个MapPageRoute的重载方法,添加路由规则更方便了
6. Routing好处
(1) 可以方便的实现REST服务
(2)Url友好化,利于SEO和增强用户体验
(3)Controller和Action的调用规则可定制化,降低耦合,提高灵活性
7. 过滤器
(1) Filter是一种AOP模式,能够对一系列操作进行横切干扰的手段,它很大程度解耦了依赖关系,让我们的代码更加简练,功能更加丰富
(2)ASP.NET MVC中提供了4类Filter接口
1)IActionFilter
2)IAuthorizationFilter
3)IExceptionFilter
4)IResultFilter
(3)ASP.NET MVC中提供了OutputCacheAttribute,HandlErrorAttribute,AuthorizeAttribute等常用Filter实现
(4)Filter的切入过程
1)以ActionFilter为例
8. SP.NET MVC3中的Filter
(1) 提供了全局注册Filter功能
(2)提供了对ChildAction的OutputCache支持
1)结合[ChildActionOnly]使用
9. Model
(1) MVC中Model主要负责维持数据状态,将数据从数据存储器中检索并传递给控制器,客户端传送过来的数据经过处理后再传回数据存储系统中,是MVC中较重的一层
(2)ASP.NET MVC框架本身并不关心数据的存储系统,并通过一些额外的帮助类和Model绑定机制简化了Model的使用
1)具备自绑定机制
2)具备自验证机制
(3)ASP.NET MVC3 Model的改进
1)ASP.NET MVC3 Model主要改进了验证机制
->数据验证(Data Annotations)
->客户端验证(Client Validation)
->远程验证(Remote Validation)
->自验证(Self Validation)
(4)数据验证
1)通过System.ComponentModel.DataAnnotations的方法集合进行验证,并对客户端验证产生一些便利影响
2)可以通过继承ValidationAttribute实现自定义验证的Attribute
(5)客户端验证
1)使用Jquery的验证插件
2)jquery.validate.unobtrusive.mis.js实现客户端验证
->启用客户端验证
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
->引用JQuery
<script src="http://www.cnblogs.com/Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="http://www.cnblogs.com/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
->特殊的验证
@{
Html.EnableClientValidation();
}
(6)远程验证
1)在Model的中使用跟RequiredAttribute相似
1)[Remote("验证的Action名","控制器名",ErrorMessage="远程验证为未通过的错误消息")]
2)注意
1)用于远程验证的Action必须是HttpGet的,Post提交无效
2)Action返回的结果是JsonResult,不是直接返回布尔值
(7)自验证
1)在Model中结合ValidationContext和ValidationResult来提供验证
public IEnumerable<ValidationResult> Validate(ValidationContext validationResult)
{
if(EndDate<=StartDate)
{
yield return new ValidationResult("结束时间必须大于开始时间");
}
}
10. 最佳实践
(1) 分层设计
1)多个项目
2)分离关注点
3)可替换的数据访问层
(2)Repository模式(业务层)
1)将数据的增删改查(CRUD)操作封装到Repository中
2)业务逻辑/数据验证封装到Service中
3)Controller调用Respository和Service
(3)PRG模式(方法)
1)POST
2)Redirect
3)GET
4)PRG模式是用来确保修改数据只发生一次
(4)保持视图中代码量最小化
1)视图中不要含有数据处理的逻辑代码
2)视图中要避免包含大的代码块
3)构建多个试图/局部视图
4)使用适当的@Helper和@Function语法
(5)跟神奇的字符串说"拜拜了"
1)ASPX模式
@ViewData["Message"]
@ViewData["TotalCount"]
2)Razor模式
@Model.Message
@Model.TotalCount
3)尽量使用特定的Model,而避免使用ViewData/ViewBag
(6)DomainModel(领域模型)!=ViewModel(视图模型)
1)符合需求的最小化ViewModel
1)有效验证
2)高安全性
3)高性能
2)使用一些Mapping工具,做双向映射填充
1)AutoMapper,EmitMapper,ValueInjecter
2)自定义的ORM-GenerPoint.ORM
3)使用专门的ViewModel填充逻辑,轻松解决国际化/本地化
(7)使用新的AJAX Helper
1)Web.Config中德appSettings
<add key="UnobtrusiveJavaScriptEnabled" value="true">
2)视图中引用jquery.unobtrusive-ajax.js
3)视图中调用AJAX Helpers
1)@Ajax.ActionLink("Home","Index",new AjaxOptions{UpdateTargetId="main"})
2)<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#content" href="/">Home</a>
(8)视图中尽可能的写HTML代码
1)尽可能写纯HTML代码
2)不要为了隐藏HTMl,而故意自定义Html.Submit之类的Helper
3)尽可能不使用WebForm控件做视图代码渲染
(9)IIS Express 7.5
1)具有完整的Web服务器功能
1)SSL
2)网址重写
3)可对<System.webServer>的配置进行本地测试
4)IIS7.X其他的模版集合
2)轻量级
1)<5M
2)不需要管理员账户
3)高性能
11. 关于性能优化的软实力
(1) 了解HTTP,Cache,Ajax各种基础知识
(2)能够针对整体Web执行环境进行分析与架构规划
(3)能够设计出妥当的缓存策略
(4)能够进一步针对网站性能进行数据话分析
12. 关于性能优化的硬功夫
(1) 熟悉.net/C#/ASP.NET MVC框架与核心原理
(2)能够进一步针对项目进行妥善规划,做好关注点分离设计
(3)熟悉Profiling技术,能够分析出个环节的性能瓶颈
(4)能够针对各种环境进行代码优化,提升程序的执行性能
13. 决定WEB性能的关键要素
(1) Web性能优化基础-HTTP
1)http是无状态的
2)一个网页包含了N次HTTP请求
(2)分析网页打开时的Http状态
1)Fiddler
2)IE10 Developer Tools
(3)客户端优化
1)HTTP请求次数减少
2)下载所使用的带宽
3)DNS查询的时间长短
4)CSS显示的速度
5)JavaScript调用的速度
(4)服务端优化
1)IIS
->控制客户端
HTTP Cache Control
->控制服务器端
将数出缓存(Output Caching)
提升数据库查询速度
2)ASP.NET MVC
->调用性能改善
->适当的缓存策略
(5)[SeesionState]
1)使用SessionState属性
控制Controller访问阶段状态数据(Session)的方式
2)注意:关闭Session后不能在使用TempData传递信息
(6)[OutputCache]
1)Html.Action与Html.RenderAction支持Output Caching
->@{Html.RenderAction("ActionName")}
->@Html.Action("ActionName")
2)ChildAction终于支持OutputCache属性
->[ChildActionOnly]
->仅支持Duration,VaryByCustom与VaryByParam参数
->不能使用CacheProfile参数
(7)改变ViewEngine的默认设置
1)移除多余的ViewEngine以提升解析View的速度
->ViewEngines.Engines.Clear();
->ViewEngines.Engines.Add(new RazorViewEngine());
2)也可以通过这种方式变更载入View的顺序
->默认是WebFormViewEngine优先处理
->ViewEngines.Engines.Add(new WebFormViewEngine());
(8)避免闯入为null给视图(View)
1)Html.TextBoxFor(m=>m.Name)
->当传入null时会引发Exception,但会被try/catch掉
->public ActionResultInsert(){
return View(new Products());
}
(9)关闭Web.Config的debug模式
1)<compilation debug="False" targetFramework="4.0" />