zoukankan      html  css  js  c++  java
  • WebForm和Asp.Net MVC的理解

    我对WebForm和Asp.Net MVC的理解

     

    比较WebForm和Mvc的请求处理方式

    首先简单了解一下Asp.Net中怎么对页面进行请求处理的:

      在管道的第7-8个事件之间,有一个MapHttpHandler类型,在这个类型的Execute方法中中会通过url去创建一个用于后续处理请求的HttpHandler对象。

        判断HttpContext有没有去指向一个具体的HttpHandler处理程序,如果已经指向了一个HttpHandler,那么就返回这个HttpHandler;(Mvc指向一个具体的Handler)

        否则根据url请求去反射创建一个一般处理程序或者Page页面;(一般处理程序或Page页面)

      在管道第11-12个事件之间,有一个CallHandlerExecutionStep类型,它的Execute方法会拿到上面返回的HttpHandler对象,执行HttpHandler的ProcessRequest方法。

        

    WebForm会根据url指定的处理程序名称去反射创建一个HttpHandler,如:http://www.ermao.com/webform.aspx;

    应用程序可以找到WebForm.aspx文件,通过反射去创建这个处理程序,执行其ProcessRequest方法;

    Asp.Net MVC的请求处理:

      试想一下,Mvc可以这样么?Mvc的url并没有指向一个具体的页面,没有文件后缀名,而且url是不区分大小写的。那么它怎么创建Controller的呢?   

      在MVC中,在Global中注册了一个全局的路由表,当应用程序第一次被请求的时候,Mvc会反射到所有实现了IController接口、且以Controller结尾的类的类型,放在一个名为controllerTypes的类型集合中。

      在系统默认的Config文件中,在第7个事件中注册了一个UrlRoutingModule,请求到来时,UrlRoutingModule会根据url请求和路由表,匹配一条路由数据(RouteData),然后根据路由数据(RouteData)和上下文对象(HttpContext)最终获得一个HttpHandler方法,这个HttpHandler具体类型就是MvcHandler,然后调用了HttpContext的RemapHandler方法,指向了一个MvcHandler。

      上面提到,MapHttpHandler中,判断是否指向一个具体的HttpHandler,Mvc就是注册了第7个事件,最终获取并指向了MvcHandler,这样Mvc就继续在管道中流动了。

      接下来就是CallHandlerExecutionStep中怎么去处理MvcHandler了,在MvcHandler的ProcessRequest中,它会获取到一个默认的ControllerFactory,根据RouteData中的Controller名、Action名,然后和上面说道的controllerTypes名进行忽略大小写的比较,匹配到一个controllerTypes中的一个Controller类型,进一步通过反射回去到Action名的方法,一同执行Action方法和过滤器,最后返回一个视图结果(WebForm试图或Razor或其他视图),渲染视图。

      WebForm的请求方式可以看出,Url地址并不友好,动态后缀也会影响到SEO,为了SEO优化我们不得不去做一些Url重写或者注册路由。

      在Asp.Net MVC中,Url地址是直接使用的路由机制,这样友好的Url,无论实在用户还是开发人员还是蜘蛛爬虫,都是很友好的。

    强类型视图和ViewState

      WebForm是用了CodeBehand来进行前后台传值:

        因为前台页面继承于后台页面,所以后台页面公开的属性,前台页面可以通过<%...%>的方式去访问;

          因为前台页面所有加了runat=Server的控件,都会以变量的方式存在于后台类中,所以后台页面可以调用前台页面的控件属性;

      那么Mvc中控制器和视图是分开的,ViewData是怎么在通过Controller在Model和View之间相互传值的呢? 

        看一下这个类,我们把这个类当作一个中间类。Controller和View之间传输数据的类,

        这个类里有索引器,存储Object类型也就是我们常用的ViewData["User"]=...

        还有一个是Model属性,也就是我们在Controller中用到的ViewData.Model=...

    复制代码
     1     public class ViewDataDictionary : IDictionary<string, object>
     2     {
     3         private readonly Dictionary<string, object> _innerDictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
     4         private object _model;
     5 
     6 
     7         public object this[string key]
     8         {
     9             get
    10             {
    11                 object value;
    12                 _innerDictionary.TryGetValue(key, out value);
    13                 return value;
    14             }
    15             set { _innerDictionary[key] = value; }
    16         }
    17 
    18         public object Model
    19         {
    20             get { return _model; }
    21             set
    22             {
    23                 _modelMetadata = null;
    24                 SetModel(value);
    25             }
    26         }
    27     }
    复制代码

        再看这个,ControllerBase类中的ViewData属性和ViewBag属性

        可以看到ViewBag调用的还是ViewData,所以他们两个数据存储对象是同一个,ViewBag用了动态属性

        Action执行完成后会把ControllerContext传递给视图,视图就可以拿到ControllerBase中的ViewBag、ViewData属性了

    复制代码
             public dynamic ViewBag
             {
                 get
                 {
                     if (_dynamicViewDataDictionary == null)
                     {
                         _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
                     }
                     return _dynamicViewDataDictionary;
                 }
             }
     
             public ViewDataDictionary ViewData
             {
                 get
                 {
                     if (_viewDataDictionary == null)
                     {
                         _viewDataDictionary = new ViewDataDictionary();
                     }
                     return _viewDataDictionary;
                 }
                 set { _viewDataDictionary = value; }
             }
    复制代码

    虽说MVC没有了ViewState,但是带来了另外一个好处——强类型视图。

      这里接简单的说一下,强类型视图的源码,还没有完全读懂。希望读懂以后继续和大家探讨

      从一开始接触WebForm,就很不喜欢用ViewState,需要的时候用隐藏域或者后台类给页面一个公开的属性,写C#代码来实现数据回传,一些不需要经常改变的就直接缓存。因为没有太多用过ViewState,所以我说的对不对也不一定,但是肯定的说ViewState带来的其他负担是不可避免的,至少在客户端和服务器之间来回传递数据的时候,可以节省很多带宽,如果是内网系统,那么带宽也无所谓了。

     

      在Asp.Net MVC中,Model的绑定机制也可以实现类似于ViewState的功能,而且它比ViewState更加灵活、更强大、更加友好,也不需要在客户端和服务器端来回传递,也可以做到“快速开发”。

    WebForm还是Asp.Net MVC

        WebForm:  

            优点:    1.提供了大量的服务器端控件,可以实现快速开发。

                  2.ViewState回传数据很方便。

                  3.学习成本低。

            缺点:  1. 封装太强,虽然学习成本低,很多底层东西让初学者不是很明白。

                  2. 自定义控制不灵活,不利于美工和开发人员的配合,往往那些服务器控件处理稍有不慎就会导致出错。

                  3. ViewState在页面中的传递。

       Asp.Net MVC:

            优点:   1.很容易将复杂的应用分成Model(ViewModel)、View、Controller三个组件模型,将处理后台逻辑代码与前台展示逻辑进行了很好的分离,属于松耦合关系,在大项目应用中,更易于敏捷开发,有很强的可扩展性。

                  2.因为没有服务器端控件,所以程序员控制的会更加灵活,页面更加干净,没有viewstate。

                  3.通过修改路由规则,可以控制生成自定义的url,因此控制生成seo友好的url将更加容易。

                  4.强类型view实现、Razor视图、Model绑定机制、Model的验证机制,更安全高效。

            缺点: 学习成本高,结构复杂,对未变化数据的不必要的频繁访问,也将损害操作性能,对于中小型网站开发,分层显得很繁琐,没有必要。

      不过我不认为MVC能取代WebForm,因为我们可以很好的利用CodeBehind,利用它的一些优势也可以去开发高性能的互联网网站,相对MVC来说要简单很多。

  • 相关阅读:
    多帐套,多组织 登录系统设计
    Git常用命令速查05
    一步步搭建java信息管理系统00
    Git常用命令速查04
    Git常用命令速查03
    Git常用命令速查02
    Git常用命令速查01
    无法创建k/3中间层组件或组件正在调用中间层问题解决
    jQuery.i18n.properties实现前端国际化
    ORACLE telnet 1521 不通及ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务的解决
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3418668.html
Copyright © 2011-2022 走看看