视图

视图的作用

       大部分的控制器操作需要以HTML格式动态显示信息,而视图的职责就是向用户提供界面。即,当控制器处理完用户的url请求后,就要将显示的内容委托给视图。通过控制器向视图提供一些信息,所以它会传递一个数据转移对象,叫做模型。视图将这个模型转换为一个适合显示给用户的格式。在mvc中,完成这一过程需要两步,其一是检查由控制器提交的模型对象,另一个是将其内容转换为HTML格式。

视图基础

@model List<MvcMusicStore.Models.Album>
@{
     ViewBag.Title = "ASP.NET MVC Music Store";
}
<div id="promotion">
</div>

<h3><em>Fresh</em> off the grill</h3>

<ul id="album-list">
    @foreach (var album in Model)
    {
        <li>
            <a href="@Url.Action("Details", "Store",
                new { id = album.AlbumId })">

                <img alt="@album.Title" src="@album.AlbumArtUrl" />
                <span>@album.Title</span>
            </a>
        </li>
    }
</ul>

上述代码阐述控制器将显示的内容委托给视图的过程。其中需要着重理解的就是Razor语法。

视图约定

        控制器之所以可以通过简单地调用return View()来渲染视图,还不需要指定视图的文件名,是因为它们利用了mvc框架的一些隐式约定,这些约定定义了视图选择逻辑。在每一个控制器的View文件夹中,每一个操作方法都有一个同盟的视图文件与其对应,这就提供了视图与操作方法关联的基础。
        虽然存在这一约定,但是这一约定是可以重写的,即return view("试图文件名")。注意,没有后缀。在其他一些应用中,我们可能需要指定完全位于不同目录结构中的视图。针对这种情况,我们可以使用带有~符号的语法来提供视图的完整路径,但这种方式必须提供视图的文件扩展名。

强类型视图

        前面例子中提到的ViewBag通常用于处理较为简单的数据,但在处理实际数据时,就显得不足了,此时,就需要使用强类型视图。

        强类型视图允许设置视图的模型类型,因此,我们可以从控制器向视图传递一个在两端都是强类型的模型对象。在Controller方法中,可以通过向重载的View方法中传递模型实例来指定模型。第二步是告知视图哪种类型模型正在使用@model声明。例如:
 

@model List<MvcMusicStore.Models.Album>
@{
     ViewBag.Title = "ASP.NET MVC Music Store";
}

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

@using MvcMusicStore.Models
@model List<MvcMusicStore.Models.Album>

对于在视图中经常使用的名称空间,一个较好的方法就是在Views目录下的web.config文件中声明。
 

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="MvcMusicStore" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

理解ViewBag、ViewData和ViewDataDictionary

       须知,ViewBag和强类型模型都是通过ViewDataDictionary传递的。从技术角度讲,数据从控制器传送到视图是通过一个名为ViewData的ViewDataDictionary(这是一个特殊的字典类),因此我们可以使用标准的字典语法设置或读取其中的值。

 ViewData["currentdate"] = DateTime.Now;

ViewBag是ViewData的动态封装器

ViewBag.currentdate = DateTime.Now;

以上两种表示方法,其效果是一样的,从技术上来讲并无差异。但依然有些许区别,一个明显的差异就是只有当要访问的关键字是一个有效的C#标识符时,ViewBag才起作用。举例说明:
 

ViewData["current date"] = DateTime.Now;

我们在这里存了一个值,但却不能通过ViewBag去获取。

另外,动态值是不能作为一个参数传递给扩展方法的,因为C#编译器在编译时必须知道每一个参数的真正类型,若要使用ViewBag,则需要先进行类型强制转换,但若是使用ViewData,则不需要。ViewDataDictionary是一个特殊的字典类,而并不只是一个通用的Dictionary。原因之一在于,它有一个额外的Model属性,允许向视图提供一个具体的模型对象。因为ViewData中只能有一个模型对象,所以使用ViewDataDictionary向视图传递具体的类十分方便。

视图模型

       视图通常需要显示各种没有直接映射到域模型的数据,例如使用ViewBag为下拉列表提供表单选项。
 


ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", album.GenreId);
ViewBag.ArtistId = new SelectList(db.Artists, "ArtistId", "Name", album.ArtistId);



div class="editor-field">
    @Html.DropDownList("GenreId", String.Empty)
    @Html.ValidationMessageFor(model => model.GenreId)
</div>
 <div class="editor-field">
     @Html.DropDownList("ArtistId", String.Empty)
     @Html.ValidationMessageFor(model => model.ArtistId)
</div>

HTML编码

     在多数情况下都需要视图显示用户输入,故而总是会存在潜在的跨站脚本注入攻击,值得庆幸的是,Razor表达式是用HTML自动编码的。

@{
    ViewBag.Title = "Create";

    var message = "<script>alert(111)</script>";
}

上述代码并不会出现弹窗,而是会呈现编码的HTML。

若想要展示HTML标记,就返回一个System.Web.IHtmlString对象的实例,Razor并不对它进行编码,即@Html.Raw(message)

布局

     Razor的布局有助于使应用程序中的多个视图保持一致的外观。布局的作用是毋庸置疑的,它可为网站定义公共模板,或只是其中的一部分。公共模板包含一个或多个占位符,应用程序中的其他视图为它们提供内容。从某些角度来看,布局很像视图的抽象基类。

ViewStart

    每一个视图都使用Layout属性来指定它的布局,如果多个视图使用同一个布局,就会产生冗余,并且很难维护。_ViewStart.cshtml页面可以用来消除这种冗余。这个文件中的代码先于同目录下任何视图代码的执行。这个文件也可以递归应用到子目录下的任何视图。

因为这个代码先于任何视图运行,因此一个视图可以重写Layout属性的默认值,从而重新选择一个不同的布局。

指定视图部分

      除了返回视图之外,操作方法也可以通过PartialView方法以PartialViewResult的形式返回部分视图。

这种情形下,渲染的是视图Message.cshtml,但是如果布局是在_ViewStart.cshtml页面指定而不是在视图中直接指定,将无法渲染布局,除此之外,别无二致。

须知,视图引擎的用途较为有限。它们的目的是获取从控制器传递给它们的数据,并生成经过格式化的输出,通常是HTML格式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值