zoukankan      html  css  js  c++  java
  • ASP.NET MVC 中 View 的设计

    1. 前言

    感觉有好长时间没有接触View 了,周末闲来无事,翻翻书桌上的书来回顾回顾ASP.NET MVCView的相关内容。

    2. View概述

    View 通过应用程序在Action 中返回 ViewResultPartialViewResult ,在运行阶段内部调用ExecuteResult 方法而产生模版转换(transforamtion),将运行阶段运算后产生的Model 经由模版引擎(template engine) 进行转换,从而生成HTML页面代码,输出到浏览器。

    //_ViewStart.cshtml
    @{
      Layout = "~/Views/Shared/_Layout.cshtml";
    }
    

    _ViewStart.cshtml的默认Layout 行为并不适用于 Partial View 部分试图,Partial View 不会引用这项指定。

    2.1 Layout 的结构


    下面是Layout 的示例代码:

    <!--Layout 示例-->
    <html>
    <head>  
      <titile>@ViewBag.Title</titile>
      @RenderSection("head")
    </head>  
    <body>
      <div class ="header">
        <!--这里放header 的内容-->
      </div>
      <div class ="main">
        <div class = "aside">
          <!--这里放侧边栏拉或者菜单等等-->
          @RenderSection("sideBar", required:false)
        </div>
        <div class = "content">
          @RenderBody();
        </div>
      </div>
      <div class= "footer">
        <!--这里放页面底部的内容-->
      </div>
      @RenderSection("Script",required:false)
    </body>
    </html>
    

    2.2 RenderSection


    @RenderSection具有一个必要参数作为区域名称,并且有一个可选参数required, 省略required 参数或者设置required:true 用来指定套用这份Layout View是否必须满足这个区域,如果没有提供该区域,会报错。

    <!--@RenderSection示例-->
    @{
      Layout = "~/Views/Shared/_Layout.cshtml";
    }
    @section head{
      <meta name="description" content = "This is a test View By Robert."/>
    }
    @section sideBar{
    <h2>
      Hello, Are you Ok?
    </h2>
    <ul>
      <li>
        <a href ="http://www.cnblogs.com">cnblogs</a>
      </li>  
      <li>
        <a href = "http://q.cnblogs.com">q.cnblogs.com</a>
      </li>
    </ul>
    }
    hahahhaha
    

    2.3 Layout 与View 的执行顺序


    在执行顺序上,View 会被优先执行,然后被View引用的Layout 执行,这一点经常会被误解为相反的情况。例如在程序中以ViewBagViewDataViewLayout 之间进行变量的传递,就会有执行顺序的问题需要考虑,因此一开始需要特别留意。

    3 View 获取数据的方法

    下面用一个表来展现几种传递数据的方式:

    方式 优点 缺点
    Model 强类型,得以在编译期间进行类型检查 当以string 类型作为ViewModel 时会有一点小麻烦
    ViewData 不需要建立ViewModel 类即可进行传递数据 弱类型,无编译期间类型检查
    ViewBag 不需要建立ViewModel 类即可进行传递数据 弱类型,无编译期间类型检查
    TempData 不需要建立ViewModel 类即可进行传递数据,可以跨Action传递 弱类型,无编译期间类型检查

    Model类型就不多说了,接下来讲一下 ViewBagViewData以及TempData

    3.1 ViewData 和ViewBag

    ViewDataController 实例中的属性,类型为ViewDataDictionaryViewDataDictionary 实现了IDictionary<string,object> , 将Dictionary中的TValue 泛型参数声明为object,故可以放置任意类型数据。

    //赋值
    ViewData["Now"] = DateTime.Now;
    
    //使用
    @ViewData["Now"]
    
    //读取
    var dateTime = (DateTime)ViewData["Now"];
    

    ViewBag Controller 实例中的属性,类型为dynamic, 与ViewData性质完全相同,只是使用的机制稍有不同。

    //赋值
    ViewBag.Now = DateTime.Now;
    
    //使用
    @ViewBag.Now
    
    //读取
    var dateTime = (DateTime) ViewBag.Now;
    

    若以“@ViewBag.自定义属性” 或 “@ViewData["自定义属性"]”的方式在页面中呈现内容,是不需要考虑类型转换的。由于都会以ToString 方法强制为字符串输出,因此在只是输出的简单情况下不必编写复杂的类型转换程序代码。

    3.2 TempData

    TempDataController 实例中的属性,类型为TempDataDictionaryTempDataDictionary 实现了IDictionary<string,object>

    各种特性让TempData 行为看起来与ViewData ViewBag 相似,但实际上存放在TempData 的数据只要经过一次读取就会消失在容器中,另一个特性是如果数据只存不取,那么这份数据的默认有效期与ASP.NET Session 一样长,未经调整的Session 有效期为20分钟。在ASP.NET MVC 内部的原因是TempData 通过内部的SessionStateTempDataProvider 实现将暂存数据放置于Session 中。

    4 Layout 嵌套

    比如下面这张图,(画的略丑)

    那么我用Layout 的代码如何设计呢?如下所示:

    <!--_Layout.cshtml-->
    <html>
      <head>
        <link rel = "stylesheet" href ="~/Content/test.min.css"/>
        @RenderSection("head",required:false)
      </head>
      <body>
        <div class = "header">
          <!-- 放Logo 啥的-->
        </div>
        <div class = "content">
          @RenderBody();
        </div>
        <div class = "footer">
          <!--页面底部-->
        </div>
        <script src = "~/Scirpts/test.min.js"></script>
        @RenderSection("scripts",required:false)
      </body>
    </html>
    

    接下来是_AsideLayout.cshtml

    <!--_AsideLayout.cshtml-->
    @{
      Layout = "~/Views/Shared/_Layout.cshtml";
    }
    @section head
    {
      <!-- 这里放需要在head 中额外加入的内容--> 
      <!--可以继续保留 否则head section 到此为止-->
      @RenderSection("head",required:false)
    }
    @section scipts{
     <!-- 这里和上面一样,继续保留 供其他调用使用--> 
      @RenderSection("scripts",required:false)
    }
    <div class = "aside">
      @RenderSection("sideBar", required:false)
    </div>
    @RenderBody()
    

    这样就很完美了。

  • 相关阅读:
    vuejs 实战 双向数据绑定
    ubuntu16安装cuda,cudnn,gpu版opencv
    ubuntu编译安装nginx并且配置流服务器
    安装使用mongodb
    c++ 编译安装ffmpeg
    apache2 日志文件太大的解决方案
    sql注入
    制作自己的电子词典
    python传递可变参数
    工厂模式
  • 原文地址:https://www.cnblogs.com/xiyin/p/6848507.html
Copyright © 2011-2022 走看看