视图(View) – ASP.NET MVC 4 系列

时间:2022-02-18 23:46:49

       精心编写的整洁代码是开发一个可维护 Web 应用程序的基础。但用户在浏览器中访问时,这些工作他们是看不见的。用户对应用程序的第一印象,以及与应用程序的整个交互过程都是从视图开始的。

       按照约定,每个控制器在 Views 目录下都有一个对应的文件夹,其名称与控制器一样,只是没有 Controller 后缀名。在每一个控制器的 View 文件夹中,每一个操作方法都有一个同名的视图文件与其相对应,这就提供了视图与操作方法关联的基础

       操作方法通过 View 方法返回 ViewResult 对象,如默认模板中的 Home 代码如下:

public ActionResult Index()

{

    ViewBag.Message = "I like cake!";

    return View();

}

       当不指定视图名称时,操作方法返回的 ViewResult 对象将按照约定来确定视图。它会在目录 /Views/ControllerName(不带 Controller 后缀) 下查找与 action 名称相同的视图,这种情况下默认选择的视图便是 /Views/Home/Index.cshtml。

       这一约定是可以重写的,如果想让 Index 操作方法渲染一个不同的视图,可以向其提供一个不同的视图名称:(仍会在 Home 文件夹中寻找指定视图)

return View("NotIndex");

       另外,在一些应用中,还可能需要指定完全位于不同目录结构中的视图,针对这种情况,可以使用带有“~”符号的语法提供视图的完整路径:

return View("~/Views/Example/Index.cshtml");

       注意,为了在查找视图时避开视图引擎的内部查找机制,使用这种语法时,必须提供视图的文件扩展名

ViewData 和 ViewBag

       从技术角度讲,数据从控制器传送到视图是通过一个名为 ViewData 的 ViewDataDictionary(这是一个特殊的字典类)。可以使用标准的字典语法设置或读取其中的值:

ViewData["CurrentTime"] = DateTime.Now;

       但现在有了更简单的语法,它利用了 C# 4.0 的 dynamic 字段。ViewBag 是 ViewData 的动态封装器,这样我们就可以使用下面的语法:

ViewBag.CurrentTime = DateTime.Now;

       因此,ViewBag.CurrentTime 等同于 ViewData["CurrentTime"] 。两者之间并不存在真正的技术差异,ViewBag 只是更受欢迎的语法而已

       但二者之间的一些关键差异还是需要知道的:

  1. 当要访问的关键字是一个有效的 C# 标识符,ViewBag 才起作用。如果在 ViewData["Key With Spaces"] 中存放一个值,ViewBag 根本无法使用,因为根本不能通过编译!
  2. 动态值不能作为一个参数传递给扩展方法,C# 编译器为了选择正确的扩展方法,在编译时必需知道每一个参数的真正类型。如果其中任何一个参数是动态的,那么就不会通过编译,例如,@Html.TextBox("name",ViewBag.Name); 要使这行代码通过编译,有 2 种办法,第一是使用 ViewData["Name"],第二是转换为具体类型 (string)ViewBag.Name。

强类型视图

       假设需要编写一个显示 Album 实例列表的视图,一种简单方法就是通过 ViewBag 属性把那些 Album 实例添加到视图数据字典中,然后再视图中迭代它们。

public ActionResult List()

{

    var albums = new List<Album>();

    for (int i = 0; i < 10; i++)

    {

        albums.Add(new Album(Title = "Product " + i));

    }

    ViewBag.Albums = albums;

    return View();

}

<ul>

    @foreach (Album A in ViewBag.Albums as IEnumerable<Album>)

    {

        <li>@a.Title</li>

    }

</ul>

       注意,枚举之前需要将动态的 ViewBag.Albums 转换为 IEnumerable<Album>类型。

       为了使视图代码干净整洁,这里也可以使用 dynamic 关键字,但是当访问每个 Album 对象的属性时,就失去了智能感知功能。

<ul>

    @foreach (dynamic p in ViewBag.Albums)

    {

        <li>@p.Title</li>

    }

</ul>

       如果既能获得 dynamic 下的简洁语法,又能获得强类型和编译时检查的好处(比如正确的输入属性和方法名称)就完美了,可喜的是,强类型的视图可以做到这一点。

       另外,ViewData 是 ViewDataDictionary 类型的,而不仅是一个通用的  Dictionary。之所以这样,是因为它有一个额外的 Model 属性,可以用来在视图中获取指定的模型对象,ViewData 中只能包含一个模型对象

public ActionResult List()

{

    var albums = new List<Album>();

    for (int i = 0; i < 10; i++)

    {

        albums.Add(new Album(Title = "Product " + i));

    }

    return View(albums);

}

       后台首先会把传给 View 方法的值赋给 ViewData.Model 属性,然后告知视图哪种类型的模型正在使用 @model 声明。注意,这里需要输入模型类型的完全限定类型名:

@model IEnumerable<MvcMusicStore.Models.Album>

<ul>

    @foreach (Album p in Model)

    {

        <li>@p.Title</li>

    }

</ul>

       如果不想输入模型的完全限定类型名,可使用 @using 关键字声明:

@using MvcMusicStore.Models

@model IEnumerable<Album>

<ul>

    @foreach (Album p in Model)

    {

        <li>@p.Title</li>

    }

</ul>

视图模型

       视图通常要显示各种没有直接映射到域模型的数据。例如,有时需要显示商品附带的其他信息,比如当前登录系统的用户名、该用户是否有权限编辑商品等。把与视图主模型无关的数据存放在 ViewBag 属性中,可以很容易实现这些数据在视图中的显示,也是一个灵活的方法。

       但这并不适用于每个人。如果要严格控制流入视图的数据,就必须使所有数据都是强类型数据,以便视图编写人员能够利用智能感知功能。可能采用的方式是编写自定义的视图模型类,这个模型仅限于向视图提供信息的模型。(这里说的视图模型不是 Model View ViewModel,MVVM 模式中的视图模型概念)

       例如,如果需要一个购物车汇总页面,用来显示商品列表、商品总金额、显示给用户的消息,就可以创建 ShoppingCartSummaryViewModel 类,如下所示:

public class ShoppingCartSummaryViewModel 

{

    public IEnumerable<Product> Products { get; set; }

    public decimal CartTotal { get; set; }

    public string Message { get; set; }

}

       然后可以使用 @model 指令,将这个模型强制性的输入到一个视图:

@model ShoppingCartSummaryViewModel

       这就在不需要改变 Model 类的情况下带来了强类型视图的益处,其中包括类型检查、智能感知以及免于转换无类型的 ViewDataDictionary 对象。

添加视图

       在 HomeController 中添加一个 Edit 操作方法,右击操作方法添加一个视图:

public ActionResult Edit()

{

    return View();

}

视图(View) – ASP.NET MVC 4 系列

       创建为分部视图时,意味着要创建的视图不是一个完整的视图,因此,Layout 选项是不可用的。

       使用布局页,对于 Razor 视图引擎来说,如果使用默认布局,就没必要指定了,因为在 _ViewStart.cshtml 中已经指定了布局。这个选项是用来重写默认布局文件的。

视图(View) – ASP.NET MVC 4 系列

视图(View) – ASP.NET MVC 4 系列的更多相关文章

  1. Razor 视图引擎 &ndash&semi; ASP&period;NET MVC 4 系列

           Razor 视图引擎是 ASP.NET MVC 3 开始扩展的内容,并且也是默认视图引擎.        Razor 通过理解标记的结构来实现代码和标记之间尽可能顺畅的转换.下面的例子演 ...

  2. ASP&period;NET MVC深入浅出系列&lpar;持续更新&rpar; ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结&lpar;3&rpar;&lpar;C&num;6&period;0和C&num;7&period;0新语法&rpar; 第三节:深度剖析各类数据结构&lpar;Array、List、Queue、Stack&rpar;及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节&colon; 总结Quartz&period;Net几种部署模式&lpar;IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  3. ASP&period;NET MVC 入门系列教程

    ASP.NET MVC 入门系列教程 博客园ASP.NET MVC 技术专题 http://kb.cnblogs.com/zt/mvc/ 一个居于ASP.NET MVC Beta的系列入门文章,有朋友 ...

  4. ASP&period;NET MVC学习系列&lpar;二&rpar;-WebAPI请求

    继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现 ...

  5. ASP&period;NET MVC学习系列&lpar;二&rpar;-WebAPI请求&lpar;转&rpar;

    转自:http://www.cnblogs.com/babycool/p/3922738.html 继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的g ...

  6. &lbrack;转&rsqb;ASP&period;NET MVC学习系列&lpar;二&rpar;-WebAPI请求 传参

    [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参 本文转自:http://www.cnblogs.com/babycool/p/3922738.html ASP.NET MVC学习系 ...

  7. ASP&period;NET MVC学习系列&lpar;二&rpar;-WebAPI请求 转载https&colon;&sol;&sol;www&period;cnblogs&period;com&sol;babycool&sol;p&sol;3922738&period;html

    继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现 ...

  8. 表单和 HTML 辅助方法&ndash&semi; ASP&period;NET MVC 4 系列

           这里有一个疑问,诸如在文本编辑器中输入 HTML 元素如此简单的任务,也需要任何帮助吗?的确,输入标签名称是很容易的事,但是确保 HTML 页面链接中的 URL 指向正确的位置.表单元素 ...

  9. ASP&period;NET MVC深入浅出系列

    一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模式,ViewState功不可没,通过的控件的拖拽和绑 ...

  10. 单元测试 &ndash&semi; ASP&period;NET MVC 4 系列

           在开发可测试软件的过程中,单元测试已成为确保软件质量的一个不可或缺部分.测试驱动开发(Test-Driven Development,TDD)是编写单元测试的一种方法,采用该方法的开发人 ...

随机推荐

  1. C&num;数字日期装换为中文日期

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  2. C&plus;&plus;类的底层机理

    我们首先从一个问题来阐明类的底层机理: 假如有一个类A,里面有一个成员函数get(),例如: class A { public:     void get(); } A a; 那么a.get()表示什 ...

  3. win8系统 host文件无法修改解决之道

    host文件,路径为:C:\windows\system32\drivers\etc\hosts 方法/步骤: 方法1:用notepad++打开host文件,修改和保存 方法2:(1)首先用管理管权限 ...

  4. BZOJ&lowbar;1028&lowbar;&lbrack;JSOI2007&rsqb;&lowbar;麻将&lowbar;&lpar;模拟&plus;贪心&rpar;

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1028 同一种花色的牌,序数为\(1,2,...,n\).定义"和了"为手上 ...

  5. leetcode第一刷&lowbar;Count and Say

    水题. 描写叙述的还挺麻烦的,实际上就是纸老虎,用两个string,一个存上一轮的结果,一个用来更新出这一轮的结果,每次扫描上一轮,统计一个字符出现的次数,然后把这个次数和字符增加到这一轮的字符串中就 ...

  6. AsyncTask和Handler

    AsyncTask实现的原理和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口 ...

  7. Python基础(zip方法)

    zip函数: 描述:将zip函数中的两个可迭代对象参数按对应索引值进行匹配组合,得到zip对象.(拉链式函数) zip函数简单应用如下: #-----------------zip函数-------- ...

  8. &lbrack;原创&rsqb;一款小巧、灵活的Java多线程爬虫框架(AiPa)

    1.简介 AiPa 是一款小巧,灵活,扩展性高的多线程爬虫框架. AiPa 依赖当下最简单的HTML解析器Jsoup. AiPa 只需要使用者提供网址集合,即可在多线程下自动爬取,并对一些异常进行处理 ...

  9. 3、调试AngularJs

    1.获取Angular元素: angular.element(document.querySelector('html')); a.ele.scope()  提取它的$scope对象 b.ele.co ...

  10. cas4&period;2&period;4 登添加验证码

    看了很多添加验证码的博文,唯独没有4.24的 重点看第3条,其余的和别人博文大致相同 1.首先在cas工程的web.xml增加验证码功能的支持 <!-- 验证码功能 -->      &l ...