第8讲:深入Controller

2010.9.8 苏鹏

内容介绍

-Action的调用与属性

 

预备知识

-安装Visual Studio 2010 Express

-了解ASP.Net

-了解设计模式基本概念

 

唤起Action

Routing把Url拿到之后回到RouteTable去匹配Url,匹配完之后就能找到Controller和Action。

 

-ControllerActionInvoker

它能完成四个操作:

1.找到对应的Action

2.找到当前请求对应路由发过来的参数,匹配完之后传给Action

3.调用Action方法所有的Filters(Filters是对Action的一种约束,只有经过Filters才知道Action是否真的可以执行)

4.调用ExecuteResult

 

Action匹配到Url

-从url中匹配Action名称

Action和Route是不见面的,他们都通过前面的ControllerActionInvoker来通讯。

它首先要在Route中找到Dictionary类,并找到Action的key,这里就能找到Action的名字。

 

Action选择方法

默认情况通常使用反射的方式来找到Action的工作方法。这也是要求Action方法必须都是public的原因,如果不是public就拿不到名称,也就没法完成下面的工作。

方法标准:

-不允许有NonActionAttribute标记

-构架函数,属性控制器,事件访问器不能作为制定的action方法

-继承自object的方法或者继承自Controller的方法

这三种标准是由ActionSelectorAttribute来执行验证的。

ActionNameAttribute

Action有一个命名规则,如果是一个Action方法命名为XXXCompleted,那这个方法一定要是异步调用,如果是要同步调用的方法起这种名字,就必须得在Action上面加一个别名,叫ActionName。这样ActionName匹配的时候不会匹配函数的名字,而会去匹配标记的名字。

image

 

ActionSelectorAttribute

- ActionSelectorAttribute定义

这个类的功能是验证IsValidFromRequest作最后匹配,如果匹配内容是False,这个Action就会从list中消除,如果匹配为True,这个Action就会被验证。最后我们的list会剩下一个匹配结果,这个函数就是最后被用来调用的。如果遍历之后发现匹配结果多于1个,就会抛出一个异常。如果遍历完之后发现一个Action都没有匹配上,也会抛出一个异常。

image

 

AcceptVerbsAttribute

image

它是最简单的一个Filters,它是混合了两种Http请求的一个验证方法。这就可以验证请求是否符合针对的Action,这种方式也可以解决函数的重名问题。

 

模拟Rest请求

HttpPostAttribute 对应创建模式

HttpPutAttribute 对应更新模式

HttpGetAttribute 对应读取模式

HttpDeleteAttribute 对应删除模式

有了这样的对应,我们的CRUD(Create、Read、Update、Delete)就可以用一个Url完成了。这样就进一步规范了Rest架构Web应用程序可用的一致性接口,并且对资源的操作取决于Http的方式。

 

映射参数

三种传参方式:

1.RequestFormCollection

2.RouteData(推荐)

3.QueryString

image

一旦Action方法确定了之后,就需要映射Action的参数。

 

调用Action

-使用异步的Action

IIS在启动的时候会有一个线程池,当用户发起一个请求的时候,IIS从线程池中找出一个空闲的线程,说你来响应这个请求吧,这个线程就会被设计为响应用户的请求。比如用户请求花了2秒时间完成,服务器端就会在2秒内实现阻塞,等待请求的完成,这个线程既是响应用户请求的线程,又是返回用户结果的线程。线程执行完操作返回给用户端之后,就回到线程池,因为它再次空闲了。默认情况下由于线程池的空闲线程比较多,这样做没什么影响。但是如果请求特别多,IIS吃紧,IIS就没法处理您的请求了,这时就会出现网络访问繁忙的错误。

因此,我们有时候需要异步的方式来工作。当服务器端拿到请求时,Action就唤醒一个线程,线程开启工作。线程开启工作之后就回到线程池了,工作就由后台其它的工作线程去做。工作结束之后MVC架构就会告诉IIS说我的工作运行完了,你再给我一个线程,我就可以把结果返回给你。这样的方式用户感觉没有区别,但是服务器的线程空闲比例会相对较高。

 

同步与异步的比较

使用同步方式

1.操作短小迅捷

异步操作在返回结果的时候需要再次获得线程,这个性能消耗也是要考虑的。

2.要求高可测试性

异步情况Action在发送和返回的是不同线程,这在测试的时候很难实现,状态没法追踪。

3.这个操作要求高CPU而不是高IO

使用异步操作

1.通过测试发现该操作是网站应用性能瓶颈

这种阻塞瓶颈的解决方法,除了异步Action,还有一种方法:OutputCahce,可以把Action的结果用OutputCahce缓存。这种缓存能有效缩短用户的等待时间,把用户发送的重复请求用缓存结果返回,这样可能数据不能及时保持最新,但是效果还是不错的。而异步请求对于用户来说还是没有区别的,用户该等多久还是要等多久。

2.对并行性有高要求

3.对这个操作要求高IO而不是高CPU

IO操作是整个性能下降最容易产生问题的地方,因为IO访问独占性,IO访问本身是由操作系统转发的。

 

编写异步Action

同步访问

image

异步访问

image

 

异步访问的Controller要继承自AsyncController。Action名字的结尾也只能是Async和Completed,这两个Action是一对,前者是响应Action请求,后者是返回数据给用户。这两者不能作为Action直接被调用。

在异步模式下参数传递方式也不同,需要用AsynvManager.Parameters字典类保存结果以便返回。因为同步是一个线程,而异步是两个线程,第一个线程结束之后,数据就没有了,我必须使用一个中间变量在两个线程之间传递数据,这个中间变量就是AsynvManager,它专门用来监视多变量的实现。

OutstandingOperation.Increment方法用来管理MVC当前的请求,这个操作非常重要,它主要是让MVC架构知道当前有多少个操作处于挂起状态,一旦把工作交给Action的后台以后,我们就不管了,OutstandingOperation每完成一个对应的Action,它就会-1,当它变成0的时候,我们就知道,这个Controller的工作已经完成了。对应的Completed方法就会被调用了。

 

并行操作的性能

同步访问

image

异步访问

image

分析一下异步的操作。OutstandingOperation.Increment(3),说明现在又3个操作。每个操作一旦完成,就需要调用OutstandingOperation.Decrement把操作数-1。全部做完之后,有一个Completed函数,它去把当前所有信息拿到,生成并返回。上面的三个操作都是并行的,因此执行的总时间是三个操作中最长的时间,而同步操作的执行总时间是三个操作的时间之和。这就是异步访问中的并行优势,如果一个Action有多个内容,就应该用异步并行来做。

 

对异步请求使用标签

image

异步Action的标签不能加在Completed方法之上。

 

超时

image

AsyncTimeout默认情况45秒超时。Timeout标签可以更改超时时间,NoAsync是永远不超时(不推荐)。如果直接指定在Controller上表示里面每个Action都默认加了这个标签。

 

关于异步方法调用的附加说明

如果一定要用Completed后缀的同步方法,需要使用别名

image

如果是Action方法是异步的,但是方法里面的一些步骤需要同步,就可以用Begin和End成对的函数来做

image

需要注意的一点是,Html.Action和Html.RenderAction是可以指向异步方法的,但是这个方法会以同步方式去调用。

 

更新Model层UpdateModel

image

这里更新之前首先验证ModelState是否可用,可用才更新,更新之后Redirect到Edit的Action。这里选择Redirect到其它地方,而不是直接返回一个View层的原因,是一个小技巧的时候。有时候用户提交数据的时候,看见没反应,就回去刷新,刷新便又会提交一条数据,当Post请求过来的时候,一旦完成它,就会跳到别的Edit,就可以编辑数据或者做一些别的相应的请求,而它每次刷新的时候,会导致ModelState不可用,这个时候只把当前请求结果返回,避免用户使用鼠标刷新页面导致重复数据提交。

 

验证数据

image

这个是写在Model层的。

 

安全性

永远不要不加处理的使用用户的输入(使用Html.Encode方式是很有必要的)

 

总结

-Action的调用与属性

2010.10.1

posted @ 2010-10-01 18:51  山天大畜  阅读(1489)  评论(0编辑  收藏  举报