• [MVC]View


    /Views/_ViewStart.cshtml 文件会在其他视图文档被加载之前被载入,代码如下:

    1 @{
    2     Layout = "~/Views/Shared/_Layout.cshtml";
    3 } 

    标志主板页为_Layout.cshtml。_ViewStart.cshtml文件同样可以出现在Views子目录下,实现不同的控制器下预设载入不同的主版页面。_Layout.cshtml代码结构:

     1         <header>
     2             <div>...</div>
     3         </header>
     4         <div id="body">
     5             @RenderSection("featured", required: false)
     6             <section class="content-wrapper main-content clear-fix">
     7                 @RenderBody()
     8             </section>
     9         </div>
    10         <footer>
    11             <div>...</div>
    12         </footer>

    注意代码中的@RenderSection和@RenderBody,@RenderBody在Razor主版页面中可以视为“预设坑洞”,也就是说View视图会被填入到@RenderBody的位置。

    @RenderSection在Razor主版页面中可以被视为“具名坑洞”,如果把required具名参数指定为true的话,那么所有载入这个主版页面的View页面都必须在@RenderSection中输出相应的内容,否则将产生异常。而“featured”就是坑洞的名字,因为required为false,所以不必填充该具名坑洞。MVC模板项目中Index.cshtml是这样填充的,如下:

     1 @section featured {
     2     <section class="featured">
     3         <div class="content-wrapper">
     4             <hgroup class="title">
     5                 <h1>@ViewBag.Title.</h1>
     6                 <h2>@ViewBag.Message</h2>
     7             </hgroup>
     8             <p>
     9                 To learn more about ASP.NET MVC visit
    10                 <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    11                 The page features <mark>videos, tutorials, and samples</mark> to help you get the most from ASP.NET MVC.
    12                 If you have any questions about ASP.NET MVC visit
    13                 <a href="http://forums.asp.net/1146.aspx/1?MVC" title="ASP.NET MVC Forum">our forums</a>.
    14             </p>
    15         </div>
    16     </section>
    17 }
    View Code

    Razor页面有固定的执行顺序,先执行View在执行Layout主版页面,因为View与Layout公用一个ViewDataDictionary实体,因此可以通过ViewBag将数据从View传递到Layout页面中,但反过来并不成立。

    2,@helper辅助方法

    将View页面中的部分内容或部分代码抽取出来,变成一个独立的辅助方法。{不要重复你自己的原则},示例代码如下:

     1 <table>
     2     @foreach (var item in Model)
     3     {
     4         <tr>
     5             <td>
     6                 @GenerateStr(item.ID)
     7             </td>
     8             <td>
     9                 @item.Name
    10             </td>
    11         </tr>
    12     }
    13 </table>
    14 
    15 @helper GenerateStr(int id)
    16 {
    17     <text>NO</text>@id
    18 }
    View Code

    声明@Helper辅助方法与C#中声明方法的方法非常类似,差别就是不用回传任何类型。
    如果要将这个@helper辅助方法用在多个不同的View里,可以将@helper辅助方法独立出来,放置在根目录App_Code中。

    注:添加App_Code文件夹的方式也很讲究,在项目中右键-->添加Asp.Net文件夹-->选择App_Code即可。然后在该文件夹中添加布局文件(cshtml){以习惯取代配置}

    然后将之前编写的@helper方法拷贝进来就可以了。假如说添加了UIHelper.cshtml,并声明了GenerateStr(int ID)方法,那么会声明一个UIHelper类,调用方式如下:

    @UIHelper.GenerateStr(item.ID)

     @helper辅助方法的缺陷:@helper辅助方法只能够简单的传入参数,格式化成想要的样式输出,为此Razor提供了@functions自定义函数功能。

    先通过@functions定义一个代码区域,然后把C#代码卸载里面,如果方法将执行的结果返回给View页面,则必须以IHtmlString类型返回。示例:

    1 @functions{
    2     public IHtmlString GetYesterday()
    3     {
    4         var theDay = DateTime.Now.AddDays(-1);
    5         return new HtmlString(theDay.ToShortDateString());
    6     }
    7 }
    View Code

     同样@functions方法可以用于多个不同的View中共享。不过需要注意,此时应该把@functions中的方法设置为static{静态方法的使用方式}

    3,@using引入命名空间:

    1 @using HelloMVC_2.Models
    2 @model IEnumerable<HelperTestModel >

     注意:在Views目录中存在web.config文件,<namespaces>区段设置所有View页面都会引入的命名空间,可以将常用的命名空间添加到这里,如下:

    1       <namespaces>
    2         <add namespace="System.Web.Mvc" />
    3         <add namespace="System.Web.Mvc.Ajax" />
    4         <add namespace="System.Web.Mvc.Html" />
    5         <add namespace="System.Web.Optimization"/>
    6         <add namespace="System.Web.Routing" />
    7       </namespaces>
    View Code


     

    4,View如何从Action取得数据

    使用弱类型取得数据/使用强类型取得数据。前者使用ViewData、ViewBag或TempData,也可以通过@Model属性,但Model属性的类型为object,所以是弱型别。

    强型别的方式从Controller中取得数据,在View用@model声明专用类型 如:@model Namespace.MyModel,使用强型别类型的一个好处是,可以使用VS的智能提示的功能。

    用ViewData.Model传递数据的示例代码如下:

     1         public ActionResult Test()
     2         {
     3             List<HelperTestModel> list = new List<HelperTestModel>()
     4             {
     5                 new HelperTestModel(){ID=1,Name="Bill"},
     6                 new HelperTestModel(){ID=2,Name="Paul"}
     7             };
     8             ViewData.Model = list;
     9             return View();
    10         }
    11 
    12 @using HelloMVC_2.Models
    13 
    14 @{var temp =         (System.Collections.Generic.IEnumerable<HelperTestModel>)Model;}
    15 @foreach(var item in temp)
    16 {
    17     <li>@item.ID</li>
    18 }

    注意到使用弱类型传递至View,改用强型别操作时,需要强制类型转换。注意@using 引入命名空间的使用。

    5,@HTML辅助方法

    以@Html.DropDownList()为例,代码如下:

     1             //Controller中代码示例
     2             List<HelperTestModel> list = new List<HelperTestModel>()
     3             {
     4                 new HelperTestModel(){ID=1,Name="Bill"},
     5                 new HelperTestModel(){ID=2,Name="Paul"}
     6             };
     7             //ViewData.Model = list;
     8             ViewData["List"] = new SelectList(list, "ID", "Name");
     9             return View();
    10             //View中代码示例
    11             @Html.DropDownList("List",ViewData["List"] as SelectList)            

    其中SelectList,是专门提供给项目列表有关的数据类型,如Html.DropDownList()和Html.ListBox()
    强类型的辅助方法:在原有名称上加上For,比如:Html.LabelFor();必须用@model定义View页面的参考数据模型。示例代码如下:

     1     //Model中
     2     public class Product
     3     {
     4         public int Id { get; set; }
     5         [Required]
     6         [DisplayName("产品名称")]
     7         public string Name { get; set; }
     8         [Required]
     9         [DisplayName("产品说明")]
    10         public string Description { get; set; }
    11        [Required]
    12         public int UnitPrice { get; set; }
    13     }
    14     //View中
    15 @model HelloMVC_2.Models.Product
    16 
    17 @using (Html.BeginForm())
    18 {
    19     @Html.ValidationSummary(true)
    20     <fieldset>
    21         <legend>产品资讯</legend>
    22         <div class="editor-label">
    23             @Html.LabelFor(model=>model.Name)
    24         </div>
    25         <div class="efitor-field">
    26             @Html.TextAreaFor(model=>model.Name)
    27             @Html.ValidationMessageFor(model=>model.Name)
    28         </div>
    29         <div class="editor-label">
    30             @Html.LabelFor(model=>model.Description)
    31         </div>
    32         <div class="efitor-field">
    33             @Html.TextAreaFor(model=>model.Description)
    34             @Html.ValidationMessageFor(model=>model.Description)
    35         </div>
    36         <p>
    37             <input type="submit" />
    38         </p>
    39     </fieldset>
    40 }
    View Code

     效果如图所示:

    通过上面的例子,很容易的实现了关注点分离。

    6,使用分部视图

    在ASP.NET Web Form的开发经验中,对于User Control使用比较频繁,可以减少重复的代码{不要重复你自己的原则},利于页面模块化,这个概念也被引入了ASP.NET MVC.即“分部视图”。

    分部视图把部分HTML或逻辑包装起来,方便重复引用,把分部视图放置与ViewsShared目录时,供其他的View载入。

    创建部分视图与创建普通的视图的的方式一致,特别的是需要选中“创建分部视图”复选框,并放在Shared目录下。默认情况下分部视图*.cshtml为空文档。

      使用分部视图时,不需要建立相关的Action。因为分部视图是片段的,必须要选择一个完整的页面来载入。用@Html.Partial()方法。

      在一个视图页面中,如果载入了多个分部视图,每个分部视图均可以取到原页面的ViewDataTempDataModel等数据,也就是说数据可以在各分部视图之间公用。

      分部视图除了可以直接从检视页面载入外,也可以像一般检视页面一样从Controller中使用。示例代码如下:

     1      //控制器中示例代码  
     2      public ActionResult Test()
     3         {
     4             return PartialView();
     5         }
     6        //然后创建Test的分部视图,简单起见只输入一行文本
     7     
     8      我的博客是SharpL
     9 
    10 
    11        //最后在视图页面中,通过Html.Action载入TestAction的执行结果
    12      @Html.Action("Test")

    通过Html.Action与Html.Partial载入分部视图的结果是一致的,但是过程不同,Html.Action会重新执行一遍Controller的声明周期。

    7,MVC支持两种不同的“视图模板”:分别是显示模板和编辑器模板。

      以@Html.EditorFor(m=>m.UserName)来说,@Html.EditorFor模板会依据UserName的类型以及属性(比如[DataType(DataType.Password)])来找出合适的模板,UserName的数据类型为String,因此模板名称也将为String,MVC 4中内建的编辑器模板中包括String,所以模板辅助方法会挑出String这个视图模板来执行。因为模板辅助方法在判断模板名称时,除了判断型别名称外,还会判断其属性,以Password来说,最终将会选择Password模板来执行。

    1         [Required]
    2         [DataType(DataType.Password)]
    3         [Display(Name = "密码")]
    4         public string Password { get; set; }
    View Code

     MVC4中内建了10个显示模板,其中包括EmailAddress等。

     1         [Required]
     2         [MaxLength(200)]
     3         [DisplayName("会员电子邮箱")]
     4         [DataType(DataType.EmailAddress)]
     5         public string Email { get; set; }
     6 
     7         /* 注意Email上的DataType属性 */        
     8   
     9 
    10      <div class="display-field">
    11         @Html.DisplayFor(m=>m.Email)
    12     </div>
    View Code

    EmailAddress将输出超链接,网页的HTML源码码如下:

    1     <div class="display-field">
    2         <a href="mailto:SharpL@qq.com">SharpL@qq.com</a>
    3     </div>

    8,自定义视图模板

      约定如下:

      视图模板一定要放在指定的几个规定目录下{以约定代替配置原则},显示模板路径:

    /Views/ControllerName/DisplayTemplates或者/Views/Shared/DisplayTemplates目录下。

    编辑器模板位于:

    /Views/ControllerName/EditorTemplates或者/Views/Shared/EditorTemplates目录下。

    文档名称必须等于类型名称。文档的后缀名可以是.cshtml/.vbhtml/.aspx/.ascx。先插入一段代码,如下:

    1         [NotMapped]
    2         [UIHint("Gravatar")]
    3         [DisplayName("会员Gravatar照片")]
    4         public string Gravatar { get; set; }

    [NotMapped]属性指不需要建立在数据库中,而UIHint属性指为Gravator添加自定义模板,且模板名称为”Gravatar“。
    于是我们在/Views/Shared/DisplayTemplates文件夹下新建一个”Gravatar.cshtml"文档,不需要强类型。将该视图中的@model定义为string,是由其上一级视图传递进来的,代码如下:

    1 @model System.String
    2 
    3 @{
    4     var temp = "算你狠" + Model;
    5 }
    6 <h2>@temp</h2>
    View Code

    效果如下:

     

    自定义编辑器模板与自定义显示模板的方式一致,只是约定的路径不同,示例代码如下:

     1         [Required]
     2         [UIHint("DateTime")]
     3         [DisplayName("创建会员的日期")]
     4         public DateTime CreateOn { get; set; }
     5 
     6     /*注意是EditorFor,如果是LabelFor无效,因为我们修改的是编辑器模板
     7     <div class="display-field">
     8         @Html.EditorFor(m=>m.CreateOn)
     9     </div>
    10 
    11 /*编辑器模板*/
    12 @model System.DateTime
    13 
    14 @Html.TextBox("",Model.ToString("yyyy/MM/dd"))
    View Code

    9,选用视图模板的判断顺序:

    UIHint属性优先级最高,属于自定义模板,其次是DataType,是字段的属性,最后是字段的类型。

    10,@Html.DisplayForModel()

    该辅助器方法不用传入任何参数,每条属性会挑选出适当的试图模板来输出

    11,自定义Html辅助方法

    也就是给HtmlHrlper类添加拓展方法,将方法定义在抽象类的抽象方法中。

     1     public static  class ImageHelpers
     2     {
     3         /// <summary>
     4         /// 实际上就是创建一个HtmlHelper类的拓展方法
     5         /// </summary>
     6         /// <param name="helper">要被拓展的类</param>
     7         /// <param name="url">图片网址啊</param>
     8         /// <param name="alternateText">说明文字</param>
     9         /// <param name="title">标题文字</param>
    10         /// <returns></returns>
    11         public static MvcHtmlString Img(this HtmlHelper helper,string url,string alternateText,string title)
    12         {
    13             return MvcHtmlString.Create(string.Format("<img src='{0}' alt='{1}' title='{2}'/>", url, alternateText, title));
    14         }
    15     }
    View Code

    可以以StringBuilder组字串的方式,来写Html标签,也可以用TagBuilder来写,不做详细的说明,可以参考ASP.NET MVC4开发指南中7.4.5章节的介绍。

    12,Url辅助方法

    @url.Action("ActionName")  最后输出结果为 /ControllerName/ActionName

    同时@url.RouteUrl(new {name="SharpL"})

    还有@Url.Encode("str")等等。

    @Url.Content("~/images/Logo.png") 取得网站中静态文档的网址路径。

  • 相关阅读:
    Leetcode: Longest Absolute File Path
    Leetcode: Mini Parser
    Leetcode: First Unique Character in a String
    Leetcode: Lexicographical Numbers
    Leetcode: Shuffle an Array
    Leetcode: Ransom Note
    Leetcode: Linked List Random Node
    Socket网络编程--聊天程序(7)
    Socket网络编程--聊天程序(6)
    Socket网络编程--聊天程序(5)
  • 原文地址:https://www.cnblogs.com/SharpL/p/4596044.html
Copyright © 2020-2023  润新知