在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
视图 3.1视图的作用 视图的职责是向用户提供用户界面,向它提供对模型的引用后,它会将模型转换为准备提供给用户的格式。 在ASP.NET MVC中这个过程由两部分组成: 检查控制器提交的ViewDataDictionary(通过ViewData属性访问),另一部分是将其内容转换为HTML格式 从ASP.NET MVC 3开始,视图数据可以通过ViewBag属性访问,该属性是动态的,语法简单,可以访问通过ViewData属性访问的相同数据。封装了ViewData,因此可以用类似访问属性的语法来检索字典中的值,如: ViewBag.Message等同于ViewData["Message"] 两者的差异:1、只有当要访问的关键字是一个有效的C#标识符时,ViewBag才其作用 如:在ViewBag["Key With Spaces"]中存放一个值,那么将不能使用ViewBag访问改值 2、该动态值不能作为一个参数传递给扩展的方法,因为C#编译器为了选择正确的扩展方法,在编译时必须知道每个参数的类型。 如:@Html.TextBox("name",ViewBag.Name)会编译失败,如果想编译通过有两种方法1、使用ViewData["Name"],2、(string)ViewBag.Name 在强类型视图中,ViewDataDictionary拥有一个视图渲染的强类型模型对象,该模型可能代表了实际的域对象,为方便起见,该模型对象可以通过视图的Model属性进行引用。 如:@{ Layout=null; } 控制器中的控制行为: Public ActionResult Sample(){ ViewBag.Message="Hello World"; Return View("Sample"); } 注意:该控制器将ViewBag.Message属性设置为一个字符串,然后返回一个名为Sample的视图,该视图将显示传递给ViewBag.Message属性的值 3.2指定视图 默认情况下在控制器中的操作方法返回的View()视图即与控制器名去掉Controller同名的视图,如果需要向其指定不同的视图则需在View(“OtherView")中指定要返回的视图名称即可 在一些情况下需要指定完全位于不同的目录结构中的视图,这时可以用带有~符号的语法来提供视图的完整路径,如: Public ActionResult Index() { ViewBag.Message="Hello World"; Return View("~/Views/Example/Index.cshtml"); } 3.3强类型视图 例:编写一个显示Album列表的视图,实现如下: Public ActionResult List() { Var ablums=new List<Album>(); For(int i=0;i<5;i++) { albums.Add(new Album{ Title="Olive"+i}); } ViewBag.Albums=albums; Return View(albums); } 在视图中显示如下: <ul> @foreach(var a in (ViewBag.Albums as IEnumerable<Album>)) { <li>@a.Title</li> } </ul> 但是在强类型视图中,可以这样实现: Public ActionResult List() { Var ablums=new List<Album>(); For(int i=0;i<5;i++) { albums.Add(new Album{ Title="Olive"+i}); } Return View(albums); } 视图中: @model IEnumerable<MvcMusicStore.Models.Album> <ul> @foreach(var p in Model) { <li>@p.Title</li> } </ul> 3.4视图模型 视图通常需要显示各种没有直接映射到域模型的数据,可以通过编写自定义的视图模型类来实现 3.5添加视图 l Scaffold Template ① Empty 创建一个空视图,使用@model语法指定模型类型 ② Create 创建一个视图,其中带有创建模型新实例的表单,并为模型类型的每一个属性生成一个标签和编辑器 ③ Delete 创建一个是视图,其中带有删除现有模型实例的表单,并为模型的每一个属性显示一个标签以及当前该属性的值 ④ Details 创建一个视图,显示了模型类型的每一个属性的标签及相应值 ⑤ Edit 创建一个视图,并带有编辑现有模型实例的表单,并未模型类型的每一个属性生成一个标签和编辑器 ⑥ List 创建一个带有模型实例的表单,为模型 类型的每一个属性生成一列,确保操作方法向视图传递的是IEnumerable<OliveType>类型,同时为执行创建/编辑/删除操作,视图还包含了指向操作的链接 l Reference script libiaries:指示创建的视图是否包含指向Javascript的文件集,当创建Create或Edit视图时,就需要选中这些项,如果实现客户端的验证也必须选中这些项 3.6Razor视图引擎 3.6.3代码表达式 例:@{ string root="Olive";} 想要输出结果为<span>Olive.Models</span> 但是在实际的运行中会报错,提示string没有Models的属性,可以通过将表达式用圆括号括起来的方式进行解决,即: 期望的输出结果为<li>Item_3</li> 但是实际输出的是<li>[email protected]</li> 出现这样的情况是因为Razor将其识别为邮箱地址了, 我们只需加上圆括号即可,如:<li>Item_@(item.Length)</li> 此外如下想要输出@号,可以使用两个@@用来转义 3.6.4Html编码 在许多情况下需要用视图显示用户的输入,但是这样存在潜在的跨站脚本攻击,但是Razor表达式默认用HTML编码 如下:@{string message=“<scritp>alert('Olive')</script>";} <span>message</span> 这段代码则不会弹出提示框,显示如下: <span><script>alert('Olive');<script></span> 如果想展示HTML标记,则需返回System.Web.IHtmlString对象的实例,Razor不对它进行编码,也可用Html.Row来显示 @{ String message=“<scritp>alert('Olive')</script>";} <span>@Html.Row(message)</span> 这样就可以显示弹框了 与此同时,在Javascript中将用户提供的值赋给变量时,要使用Javascript字符串编码而不是HTML编码,也就是用@Ajax.JavaScriptStringEncode方法来对用户的输入进行编码的 这样就可以有效的避免跨站脚本的攻击,如下: <script type="text/javascript"> $(function(){ Var message='Hello @Ajax.JavaScriptStringEncode(ViewBag.UserName)'; $("#message").html(message).show('slow'); }); </script> 3.6.5 Razor语法示例 1、隐式代码表达式 Razor中隐式表达式总是采用HTML编码方式 2、显示代码表达式 <span>ISBN@(isbn)</span> 3、无编码代码表达式 使用Html.Row方法来确定内容不被编码 <span>@Html.Row(model.Message)</span> 4、代码块 @{ Int x=123; String y=”because"; } 5、文本和标记组合 @foreach(var item in items) { <span>Item @item.Name.</span>} 6、混合代码和纯文本 @if(show) { <text>This is Olive</text> } 或者 @if(show) { @This is Olive } 3.6.6布局 ASP.NET MVC 3中的布局相当于WebForm中的母版页 如下布局页中部分代码: <div id=“main-content">@RenderBody()</div> 其中的@RenderBody()相当于WebFrom中的placeholder占位符 布局使用示例: @{ Layout="~</Views/Shared/Layout.cshtml"; } <span>This is main content!</span> 此外,布局中还可能有多个节,如下:部分布局页代码示: <div >@RenderBoday()</div> <footer>@RenderSeciton("Footer")</footer> 如果对视图页不做任何改变则会报错,这里需要对视图页做如下修改 @{ Layout="~</Views/Shared/Layout.cshtml"; } <p>This is a main content!</p> @section Footer{ This is the <strong>footer</strong> } @section语法为布局中定义的一个节指定了内容,在默认的情况下视图必须为布局中定义的节指定内容,但是RenderSection方法有一个重载版本,允许指定不需要的节,即为required参数传递一个false值来标记Footer节是可选的,如下: <footer>@RenderSection("Footer",false)</footer> 也可以定义一些薯条中没有定义节时的默认内容,方法如下: <footer> @if(IsSectionDefined("Footer")) { RenderSection("Footer"); } Else { <span>This is the default footer.</span> } </footer> 3.6.7 ViewStart 创建默认的ASP.NET MVC 3时,会自动生成_ViewStart.cshtml文件,指向了一个默认的布局,如果一组视图有共同的设置,则_ViewStart.cshtml文件便很有用,但是如果需要另选择布局,则需要重新指定视图的Layout属性如下: @{ Layout="~/Views/Share/others.cshtml"; } 3.7指定分部视图 除了返回视图外,操作方法也通过PartialView方法以PartialViewResult的形式返回分部视图: 如: Public ActionResult Message() { ViewBag.Message="This is Olive"; Retrun PartialView(); } 如果布局是由_Viewstart.cshtml页面指定的,则布局无法渲染。 分部视图多用于AJAX技术中的部分更新情形 如:使用JQuery将一个分部视图内容加载到使用AJAX调用当前视图中: <div id="result></div> <script type="text/javascript"> $(function(){ $('#result').load('/home/message'); }); </script> 3.8视图引擎 首先来了解下ASP.NET MVC 3的生存周期,
控制器本身并不渲染视图,它仅准备暑假,并返回一个ViewResult实例来决定显示哪个视图,控制器基类包含一个名为View的简单方法来返回一个ViewResult实例,在视图引擎后台ViewResult被调用到当前的视图引擎中来渲染该视图
第四章 模型
本章要讨论的是那些发送信息到数据库,执行业务计算并在视图中渲染的模型对象。这些对像代表着应用程序的关注的域,模型就是想要保存、创建、更新和删除对象
4.2.1基架的概念
ASP.NET MVC中基架可以为应用程序的创建、读取、更新和删除(CRUD)提供所需的样板代码。基架模板检测模型类的定义,然后生成控制器以及该控制器控制的相关视图。
ASP.NET MVC3共有三个模板可供选择:
l Empty Controller:该模板会向Controller文件夹中添加一个具有指定名称且派生自Controller类的控制器,该控制器仅带有Index操作,且在内部仅返回一个默认的ViewResult实例,不会生成任何视图
l Controller with Empty Read/Write Actions:该模板会向项目中添加一个带有Index、Details、Create、Edit和Delete操作控制器,但是还需自己为其添加代码,实现操作,并为其创建视图
l Controller with Read/Write Actions and Views,Using Entity Framework:该模板生成整套的带有Index、Details、Create、Edit和Delete操作控制器,以及相关的所有视图,还生成了与数据库交互的代码。该模板需要指定选择合适的类模型(基架检测会检测所选择的模型的所有属性,然后根据这些信息来创建控制器、视图、数据库操作等代码)和数据上下文对象名称
4.2.2基架和实体框架
EF(Entity Framework)是一个对象关系映射框架,可以在关系型数据库中保存对象,也可以利用LINQ查询语句检索那些保存关系型数据库中的.NET对象
我们之前所建的模型类中所有的属性都是虚属性,意思就是该属性不是必须的,但是它们给EF提供一个指向纯C#类集的钩子,并为EF启用了一些特性,EF需要知道模型属性值的修改时刻,在这一刻生成UPDate语句,使这些改变和数据库保持一致。
l 代码优先约定
EF对于外键关系、数据库名称等有约定,这些约定取代了以前需要提供给一个关系对象映射框架的所有映射和配置
l DbContext
在使用代码优先约定时,需要使用从EF的DbContext类派生出一个类来访问数据库。该类可以有一个以上的的DbSet<T>类型的字段,类型DbSet<T>的每一个T代表一个想要持久保存的对象
4.2.3执行基架模板
1、数据上下文
上文提到的从DbContext类继承而来的类,如下:
public class MusicStoreDB : DbContext { /// <summary> /// 用来存储Album类型的对象,相当于数据库中的Album表 /// </summary> public DbSet<Album> Albums { get; set; } /// <summary> /// 用来存储Artist类型的对象,相当于数据库中的Artist /// </summary> public DbSet<Artist> Artists { get; set; } /// <summary> /// 用来存储Genre类型的对象,相当于数据库中的Genre表 /// </summary> public DbSet<Genre> Genres { get; set; } }
如果需要访问数据库,只需要实例化这个数据上下文类即可。
2、 全部评论
专题导读
上一篇:ASP.NET命名教训-尽量避免关键字发布时间:2022-07-10下一篇:OAuthImplementationforASP.NETWebAPIusingMicrosoftOwin.发布时间:2022-07-10热门推荐
热门话题
阅读排行榜
|
请发表评论